Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL Server:quantos dias cada item estava em cada estado


Isso fornece os mesmos resultados que você está pedindo, em um formato ligeiramente diferente (mas você pode encontrar facilmente PIVOT soluções se você precisar exatamente do mesmo conjunto de resultados):
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

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

Observe que estou ignorando o PreviousState coluna da sua pergunta e estou construindo Joined porque o que realmente importa é quando o próximo estado entrou em vigor.

Problemas não tratados porque você não os descreveu em sua pergunta:1) O que fazer se o estado final atual não for Closed - ou seja, ignoramos isso ou contamos até hoje?, e 2) O que fazer se a hora do dia para cada DateChanged não é o mesmo - temos que lidar com dias parciais?