【问题标题】:find time conflicts between two dates查找两个日期之间的时间冲突
【发布时间】:2016-06-09 15:05:54
【问题描述】:

我正在处理一个应该查找两个日期之间的午餐时间的查询。 例如,午餐时间在 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”和“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 次

但我永远做不到:(

【问题讨论】:

  • 请告诉我们你尝试了什么。
  • 我写了一会儿给@date1添加分钟然后转到@date2,每次检查它的TIME是否在开始午餐时间和结束午餐时间之间,如果是真的,@CountedLunches会增加,但有点变量的变化,以防止午餐双增加

标签: sql sql-server


【解决方案1】:

这似乎有效:

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

注意 - 许多人在试图确定重叠的定义时过于复杂。我在这里使用了一个简单的定义,通常唯一可能需要更改的是决定是使用&lt; 还是&lt;=,这取决于您是否考虑了两个毗邻的时期,否则不要覆盖要重叠的相同时间段。

因此,如果您对上述查询在查询 开始 恰好在 15:30 或 在 14:00 结束

【讨论】:

  • 感谢您的正确答案和描述,但我只能选择一个答案作为正确答案。
【解决方案2】:

试试这个并根据您的要求制作 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

【讨论】:

  • 感谢您的回答,但您使用的是 DATEPART(HOUR,...) 分钟呢?!
  • 编辑了答案以供仔细考虑:)
  • 再次谢谢你,我改了,它成功了,再次谢谢你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多