Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SQL Server :quanti giorni ogni elemento era in ogni stato

Questo ti dà gli stessi risultati che stai chiedendo, in un formato leggermente diverso (ma puoi trovare facilmente PIVOT soluzioni se hai bisogno dello stesso identico set di risultati):

declare @t table (ItemId int,Revision int,State varchar(19),DateChanged datetime2)
insert into @t(ItemId,Revision,State,DateChanged) values
(1,1,'New',   '2014-11-13T10:00:00'),
(1,2,'Active','2014-11-15T10:00:00'),
(1,3,'New',   '2014-11-17T10:00:00'),
(1,4,'Active','2014-11-19T10:00:00'),
(1,5,'Active','2014-11-20T10:00:00'),
(1,6,'Closed','2014-11-22T10:00:00'),
(2,1,'New',   '2014-11-13T10:00:00'),
(2,2,'Active','2014-11-16T10:00:00'),
(2,3,'Closed','2014-11-17T10:00:00'),
(2,4,'Active','2014-11-19T10:00:00'),
(2,5,'Closed','2014-11-21T10:00:00')

;With Joined as (
    select t1.ItemId,t1.State,DATEDIFF(day,t1.DateChanged,t2.DateChanged) as Days
    from
        @t t1
            inner join
        @t t2
            on
                t1.ItemId = t2.ItemId and
                t1.Revision = t2.Revision -1
    )
select ItemId,State,SUM(Days)
from Joined
where State <> 'Closed'
group by ItemId,State

Risultato:

ItemId      State               
----------- ------------------- -----------
1           Active              5
1           New                 4
2           Active              3
2           New                 3

Nota che sto ignorando lo PreviousState colonna dalla tua domanda e sto invece costruendo Joined perché ciò che conta davvero è quando il successivo stato è entrato in vigore.

Problemi non affrontati perché non li hai descritti nella tua domanda:1) Cosa fare se lo stato finale corrente non è Closed - cioè lo ignoriamo o contiamo fino ad oggi? e 2) Cosa fare se l'ora del giorno per ogni DateChanged non è lo stesso:dobbiamo gestire giorni parziali?