2012-05-30 2 views
4

Проверьте мой SQLFiddle здесь (link)SQL: Разделение событий в несколько строк

В SQL Server 2008, у меня есть таблица события начала и конца, как на изображении ниже.

enter image description here

Мне нужно написать запрос, который позволяет мне, чтобы выяснить, сколько из каждого события упал в какую смену. Наши смены длится 12 часов и идут с 06: 00-18: 00 и 18: 00-06: 00.

Запрос должен давать результаты, подобные изображению ниже.

enter image description here

Из этого я могу затем выяснить общие длительности событий для конкретной рабочей смены.

Что я могу сделать, чтобы перейти от первого изображения, ко второму изображению?

ответ

5
With Shifts As 
    (
    Select 1 As Num 
     , Cast('2012-05-01 6:00 AM' As datetime) As ShiftStart 
     , DateAdd(hh,12,Cast('2012-05-01 6:00 AM' As datetime)) As ShiftEnd 
    Union All 
    Select Num + 1, ShiftEnd, DateAdd(hh,12,ShiftEnd) 
    From Shifts 
    Where ShiftEnd < '2012-05-30' 
    ) 
    , Segments As 
    (
    Select event_id 
     , Case 
     When Shifts.ShiftStart > event_start Then Shifts.ShiftStart 
     Else event_start 
     End As start_split_segment   
     , Case 
     When Shifts.ShiftEnd < event_end Then Shifts.ShiftEnd 
     Else event_end 
     End As end_split_segment   
     , Count(*) Over (Partition By E.event_id) As SegmentCount 
    From events As E 
     Join Shifts 
     On E.event_start <= ShiftEnd 
      And E.event_end > ShiftStart 
    ) 
Select E.event_id, E.description, E.event_start, E.event_end 
    , S.start_split_segment, S.end_split_segment 
    , Case When SegmentCount > 1 Then 1 Else 0 End As is_split 
    , NullIf(SegmentCount,1) As split_segments 
From Segments As S 
    Join events As E 
    On E.event_id = S.event_id 

SQL Fiddle version

В этом решении, я сгенерировал календарь каждой смены в начальной и конечной даты. Вы можете продлить календарь, изменив Where ShiftEnd < '2012-05-30' на более крупную дату. Обратите внимание, что если вы закончите с более чем 50 сменой или около того, вам нужно добавить Option(Maxrecursion 0); в конец запроса, чтобы снять кеп SQL Server.

+0

Молодцы! Я не могу поверить, насколько вы это сумели сделать. Это избавит меня от неприятностей. Спасибо. –

Смежные вопросы