Вот решение с подтверждением концепции, которую могут проверить все.
Я заметил, что событие Off
для C
было помечено как новое On
.Я исправил это, но это также привело меня к написанию решения, которое позволяло бы иметь событие, которое началось, но не закончилось, поэтому я включил событие открытого конца D
.
Кроме того, мое решение работает с перекрытиемпериоды.
declare @YourTable table (Item varchar(10),
EventDate datetime,
Event varchar(10))
insert into @YourTable values
('A', '2011-10-03 00:01:00', 'On'),
('B', '2011-10-03 00:01:00', 'On'),
('A', '2011-10-03 00:02:00', 'Off'),
('C', '2011-10-03 00:01:00', 'On'),
('B', '2011-10-03 00:02:00', 'Off'),
('A', '2011-10-03 00:02:02', 'On'),
('C', '2011-10-03 00:02:05', 'Off'),
('A', '2011-10-03 00:02:07', 'Off'),
('D', '2011-10-03 00:02:02', 'On')
select tOn.Item, tOn.EventDate Start, tOff.EventDate [End]
from (
select Item, EventDate,
ROW_NUMBER() Over(Partition by Item order by EventDate) EventID
from @YourTable where Event = 'On'
) tOn
LEFT JOIN (
select Item, EventDate,
ROW_NUMBER() Over(Partition by Item order by EventDate) EventID
from @YourTable where Event = 'Off'
) tOff
on (tOn.Item = tOff.Item and tOn.EventID = tOff.EventID)
Объяснено
Мы делим набор данных на 2: On
события и Off
события.Каждый из них содержит пронумерованную строку, которая перезапускается при изменении Item
.
По сути, у нас есть первый вошел первым: первый On
будет закрыт первым Off
, поэтому перекрывающиеся периоды будут поддерживаться этим запросом при таком подходе.Таким образом, каждое On
событие для A
будет иметь Event ID
, которое будет связано с корреспондентом Off
Event ID
.
Открытые периоды будут поддерживаться LEFT JOIN
.