这似乎有效:
declare @t table (StartAt datetime not null,EndBefore datetime not null)
insert into @t(StartAt,EndBefore) values
('2016-06-09T15:00:00.000','2016-06-11T10:00:00.000'),
('2016-06-09T17:00:00.000','2016-06-11T10:00:00.000'),
('2016-06-09T13:00:00.000','2016-06-11T15:00:00.000')
;With Dates as (
select MIN(DATEADD(day,DATEDIFF(day,0,StartAt),0)) as ADate
from @t
union all
select DATEADD(day,1,ADate) from Dates
where exists (select * from @t where EndBefore > DATEADD(day,1,ADate))
), Lunches as (
select DATEADD(minute,(14*60),ADate) as StartAt,
DATEADD(minute,(15*60+30),ADate) as EndBefore
from Dates
)
select
*,(select COUNT(*) from Lunches l
where l.StartAt < t.EndBefore and t.StartAt < l.EndBefore)
from @t t
我们使用两个 CTE (a) 导出所有相关日期,以及 (b) 从日期计算所有可能的午餐时间,然后最终找到所有与原始时段重叠的午餐。
结果:
StartAt EndBefore
----------------------- ----------------------- -----------
2016-06-09 15:00:00.000 2016-06-11 10:00:00.000 2
2016-06-09 17:00:00.000 2016-06-11 10:00:00.000 1
2016-06-09 13:00:00.000 2016-06-11 15:00:00.000 3
注意 - 许多人在试图确定重叠的定义时过于复杂。我在这里使用了一个简单的定义,通常唯一可能需要更改的是决定是使用< 还是<=,这取决于您是否考虑了两个毗邻的时期,否则不要覆盖要重叠的相同时间段。
因此,如果您对上述查询在查询 开始 恰好在 15:30 或 在 14:00 结束。