Время начала и окончания T-SQL из одного столбца - PullRequest
1 голос
/ 03 октября 2011

У меня есть одна таблица событий включения / выключения для разных активов.Мне нужно получить список времени начала и окончания события без использования курсора.

Источник:

Item      EventDate               Event
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     On
A         2011-10-03 00:02:07     Off

Желаемый результат:

Item      Start                   End
A         2011-10-03 00:01:00     2011-10-03 00:02:00
A         2011-10-03 00:02:02     2011-10-03 00:02:07
B         2011-10-03 00:01:00     2011-10-03 00:01:00
C         2011-10-03 00:01:00     2011-10-03 00:02:05

Ответы [ 3 ]

1 голос
/ 03 октября 2011

Непроверено ...

;WITH myCTE AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY Item ORDER BY EventDate) AS rn
   FROM MyTable
)
SELECT
   M1.Item,
   M1.EventDate AS Start,
   M2.EventDate AS End
FROM
   myCTE M1
   JOIN
   myCTE M2 ON M1.Item = M2.Item AND M1.rn+1 = M2.rn
WHERE
   M1.Event = 'On'
   AND
   M2.Event = 'Off';
1 голос
/ 03 октября 2011

Вот решение с подтверждением концепции, которую могут проверить все.

Я заметил, что событие 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.

0 голосов
/ 04 октября 2011
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')   

;with a as
(
select item, eventdate, event, ROW_NUMBER() Over(Partition by Item order by EventDate) RN 
from @YourTable
),
b as (
select item, eventdate, 0 e, rn, event from a where rn = 1
union all
select b.item, a.eventdate, case when b.event = 'Off' then b.e+1 else b.e end, a.rn, a.event
from b 
join a on b.rn + 1 = a.rn and a.item = b.item
)
select item, min(eventdate) Start, max(eventdate) [End]
 from b
group by item, e
order by item, e
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...