Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL Server:wie viele Tage sich jedes Element in jedem Zustand befand

Dadurch erhalten Sie dieselben Ergebnisse, nach denen Sie gefragt haben, in einem etwas anderen Format (aber Sie können PIVOT leicht finden Lösungen, wenn Sie genau die gleiche Ergebnismenge benötigen):

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

Ergebnis:

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

Beachten Sie, dass ich den PreviousState ignoriere Spalte aus Ihrer Frage und konstruiere stattdessen Joined denn was wirklich zählt, ist wann die nächste Bundesstaat in Kraft getreten.

Probleme, die nicht behandelt wurden, weil Sie sie in Ihrer Frage nicht beschrieben haben:1) Was tun, wenn der aktuelle Endzustand nicht Closed ist? - d.h. ignorieren wir das oder zählen wir bis heute? und 2) Was tun, wenn sich die Tageszeit für jedes DateChanged ist nicht dasselbe - müssen wir Teiltage behandeln?