2011-12-03 24 views
2

我有一张表格,其中包含重叠时间段的记录。俱乐部在SQL Server中重叠时间槽

如:日历(ID INT,起始日期日期时间,结束日期日期时间,EVENTTITLE为nvarchar(100),...)

这些记录会像

  1. 2011年1月20日08 :15 AM --- 01/20/2011 08:40 AM
  2. 01/20/2011 08:20 AM --- 01/20/2011 08:55 AM
  3. 01/20/2011 12:30 PM --- 01/20/2011 01:15 PM
  4. 01/20/2011 0下午2:00 --- 2011年1月20日下午2点45
  5. 2011年1月20日下午2时15分--- 2011年1月20日下午2点三十
  6. 2011年1月21日12: 30 PM --- 2011年1月21日下午1时15
  7. .......
  8. .......

该表代表的事件的时间表人

我想把重叠的插槽放在一起给:

  1. 2011年1月20日08:15上午--- 2011年1月20日上午08点55分
  2. 2011年1月20日下午12:30 --- 01:15 2011年1月20日PM
  3. 01/20/2011 02:00 PM --- 01/20/2011 02:45 PM
  4. 01/21/2011 12:30 PM --- 01/21/2011 01:15 PM
  5. ...
  6. ...

我被困在这个问题的部分......(我删除了我粘贴在这里的代码,因为它看起来很伤心。我使用的是第一次使用计算器。)

我的实际需求的一部分是在两个给定日期之间找到一个时间段[t](比方说25分钟),这可以适应日程安排。 [t]必须在任何一天的上午8:00到下午05:00之间找到。

+0

可能重复http://stackoverflow.com/questions/781895/checking-for-time-range-overlap-the-watchman-problem-sql – danihp

+1

试过解决方案@danihp。该解决方案假设最多有两个连续的重叠时隙。 将其应用于我的问题,在连续有3个重叠插槽的情况下失败。 –

+0

您需要查询还是对您有效的商店程序或功能?什么意思是25'时隙?你能解释这最后一点吗? – danihp

回答

2

这是一个有趣的问题。

对于给定的日期一个,让我们考虑的重叠(我进入了我所有的日期时间按照你们的,但对于1/1/2011):

SELECT  dt1.StartTime AS StartOverlap, 
       CASE 
       WHEN dt1.EndTime > dt2.EndTime THEN dt1.EndTime 
       ELSE dt2.EndTime 
       END AS EndOverlap 
FROM   datetimetest dt1, datetimetest dt2 
WHERE   dt2.StartTime > dt1.StartTime 
AND   dt2.StartTime < dt1.EndTime 

这给了我:

StartOverlap  EndOverlap 
01/01/2011 08:15:00 01/01/2011 08:55:00 
01/01/2011 14:00:00 01/01/2011 14:45:00 

太好了,我们现在知道我们不能使用重叠的开始和结束时间。

我们如何得到其他没有重叠时间?

我想看看是在重叠范围内的所有时间段,然后选择出的ID不在该日期范围:

SELECT id 
FROM (SELECT  dt1.StartTime AS StartOverlap, 
       CASE 
        WHEN dt1.EndTime > dt2.EndTime THEN dt1.EndTime 
        ELSE dt2.EndTime 
       END AS EndOverlap 
    FROM   datetimetest dt1, datetimetest dt2 
    WHERE dt2.StartTime > dt1.StartTime 
    AND dt2.StartTime < dt1.EndTime 
) AS Overlaps, datetimetest dtt 

WHERE dtt.StartTime >= Overlaps.StartOverlap 
AND dtt.EndTime <= Overlaps.EndOverlap 

这给了我所有的ID的列表在重叠中。然后,我只是选择所有的重叠情况不会条目:

SELECT StartTime, EndTime FROM datetimetest 
WHERE id NOT IN(
SELECT id 
FROM (SELECT  dt1.StartTime AS StartOverlap, 
       CASE 
        WHEN dt1.EndTime > dt2.EndTime THEN dt1.EndTime 
        ELSE dt2.EndTime 
       END AS EndOverlap 
    FROM   datetimetest dt1, datetimetest dt2 
    WHERE dt2.StartTime > dt1.StartTime 
    AND dt2.StartTime < dt1.EndTime 
) AS Overlaps, datetimetest dtt 

WHERE dtt.StartTime >= Overlaps.StartOverlap 
AND dtt.EndTime <= Overlaps.EndOverlap) 

给我:

StartTime   EndTime 
01/01/2011 12:30:00 01/01/2011 13:15:00 

然后我就可以联合两个查询一起给我所有使用的时隙的列表。

由于我们正在有效地交叉连接同一个表,因此我会为每个查询添加一个附加子句以约束日期到单个日期。

+0

该解决方案适用于一个重叠期,例如我有8:15 - 8:30,8:25-8:40,8:20 - 8:50的时间段,解决方案将失败。 –