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?