sql >> Base de Datos >  >> RDS >> Sqlserver

SQL Server:cuántos días estuvo cada elemento en cada estado

Esto le brinda los mismos resultados que está solicitando, en un formato ligeramente diferente (pero puede encontrar fácilmente PIVOT soluciones si necesita exactamente el mismo 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

Tenga en cuenta que estoy ignorando el PreviousState columna de su pregunta y, en cambio, estoy construyendo Joined porque lo que realmente importa es cuándo el siguiente entró en vigor.

Problemas no tratados porque no los ha descrito en su pregunta:1) Qué hacer si el estado final actual no es Closed - es decir, ¿ignoramos eso o contamos hasta hoy?, y 2) ¿Qué hacer si la hora del día para cada DateChanged no es lo mismo, ¿tenemos que manejar días parciales?