Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

SQL Server :combien de jours chaque élément était dans chaque état

Cela vous donne les mêmes résultats que vous demandez, dans un format légèrement différent (mais vous pouvez facilement trouver PIVOT solutions si vous avez besoin du même ensemble de résultats) :

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

Résultat :

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

Notez que j'ignore le PreviousState colonne de votre question et je construis à la place Joined parce que ce qui compte vraiment, c'est quand le suivant l'état est entré en vigueur.

Problèmes non traités car vous ne les avez pas décrits dans votre question :1) Que faire si l'état final actuel n'est pas Closed - c'est-à-dire ignorons-nous cela, ou comptons-nous jusqu'à aujourd'hui ?, et 2) Que faire si l'heure de la journée pour chaque DateChanged n'est pas la même - devons-nous gérer des journées partielles ?