這似乎工作:
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以防止雙倍增加午餐 –