在这里查看我的 SQLFiddle(链接)
在 SQL Server 2008 中,我有事件开始和结束时间表,如下图所示。
我需要编写一个查询,让我能够弄清楚每个事件中有多少属于哪个工作班次。我们的轮班时间为 12 小时,从 06:00-18:00 和 18:00-06:00 开始。
查询应产生如下图所示的结果。
由此,我可以计算出特定工作班次的总事件持续时间。
我该怎么做才能从第一张图像转到第二张图像?
在这里查看我的 SQLFiddle(链接)
在 SQL Server 2008 中,我有事件开始和结束时间表,如下图所示。
我需要编写一个查询,让我能够弄清楚每个事件中有多少属于哪个工作班次。我们的轮班时间为 12 小时,从 06:00-18:00 和 18:00-06:00 开始。
查询应产生如下图所示的结果。
由此,我可以计算出特定工作班次的总事件持续时间。
我该怎么做才能从第一张图像转到第二张图像?
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
在这个解决方案中,我生成了每个班次开始和结束日期的日历。Where ShiftEnd < '2012-05-30'
您可以通过更改为更大的日期来扩展日历。请注意,如果最终轮班超过 50 次左右,则需要Option(Maxrecursion 0);
在查询末尾添加以提高 SQL Server 的上限。