2016-06-09 69 views
2

我正在研究应该在两个日期之间找到午餐时间的查询。例如, 午餐时间为14:00 PM至15:30 PM。 ,日期为:'2016-06-09 10:00:00.000'和'2016-06-11 10:00:00.000' 午餐时间在这些日期之间发生两次。 和另一个例子:找到两个日期之间的时间冲突

 
'2016-06-09 15:00:00.000' and '2016-06-11 10:00:00.000' : 2 Times 
'2016-06-09 17:00:00.000' and '2016-06-11 10:00:00.000' : 1 Time 
'2016-06-09 13:00:00.000' and '2016-06-11 15:00:00.000' : 3 Times 

但是我还没有做到这一点:(

+0

请告诉我们你试过了什么。 – gofr1

+0

我写了一段时间给'@ date1'增加了几分钟,然后进入'@ date2',每次检查TIME是否在开始午餐时间和结束午餐时间之间,如果它是真的,'@ CountedLunches'会增加,但是a以防止双倍增加午餐 –

回答

1

根据您的要求试试这个,让tweeks:

DECLARE @date1 DATETIME = '2016-06-09 08:30:00.000'; 
DECLARE @date2 DATETIME = '2016-06-13 18:00:00.000'; 
DECLARE @lunchStart DATETIME = '2016-06-13 14:00:00.000'; 
DECLARE @lunchEnd DATETIME = '2016-06-13 15:30:00.000'; 
DECLARE @output INT = 0; 

SELECT @output = DATEDIFF(DAY, @date1, @date2) 
IF DATEPART(HOUR, @date1) > DATEPART(HOUR, @lunchStart) OR (DATEPART(HOUR, @date1) = DATEPART(HOUR, @lunchStart) AND DATEPART(MINUTE, @date1) <= DATEPART(MINUTE, @lunchStart)) 
    SET @output = @output - 1 

IF DATEPART(HOUR, @date2) < DATEPART(HOUR, @lunchEnd) OR (DATEPART(HOUR, @date2) = DATEPART(HOUR, @lunchEnd) AND DATEPART(MINUTE, @date2) = DATEPART(MINUTE, @lunchEnd)) 
    SET @output = @output - 1 

PRINT @output 
+0

感谢您的答案,但您正在使用DATEPART(小时,...) 和什么约分钟?! –

+0

编辑了分钟考虑的答案:) –

+0

再次感谢你,我改变了它,它的工作,再次感谢你 –

4

这似乎工作:

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。

+0

感谢您的正确答案和您的描述,但我只能选择一个答案作为正确的答案。 –

相关问题