这似乎工作:
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。
请告诉我们你试过了什么。 – gofr1
我写了一段时间给'@ date1'增加了几分钟,然后进入'@ date2',每次检查TIME是否在开始午餐时间和结束午餐时间之间,如果它是真的,'@ CountedLunches'会增加,但是a以防止双倍增加午餐 –