2011-05-11 90 views
0

我需要查找新的日程是否与任何现有日程重叠。检查日程是否重叠

这就是“间隔”表:

 id first    last  
    1 1900-01-01 09:00 1900-01-01 10:00 
    2 1900-01-01 15:00 1900-01-01 18:00 
    3 1900-01-01 18:01 1900-01-01 08:00 

我使用的是标量函数dbo.TimeOnly从日期时间字段提取时间的一部分。

我的选择标准如下

第一种情况

 declare @start datetime 
    declare @end datetime 

    set @start = dbo.TimeOnly('2011-may-11 08:01:00'); 
    set @end = dbo.TimeOnly('2011-may-11 15:30:00'); 

    select * from intervals where 
    (NOT (dbo.TimeOnly(last) < @start OR @end < dbo.TimeOnly(first))) 

这将返回第一和第二的记录。我从Check whether the schedule overlaps each other?

其次情况下,这个逻辑

set @start = dbo.TimeOnly('2011-may-11 07:01:00'); 
    set @end = dbo.TimeOnly('2011-may-11 08:30:00'); 

如何编写一个查询,将在第二种情况下只返回3记录的标准是什么?

UPDATE

我会给我的问题

不同的人管理一个特定的事件在一天一定持续时间的更多细节。

对于周一,计划格式是这样

Id Start  End   User Days  
    1 00:01 AM 08:00 AM  'A' 1 
    2 08:01 AM 04:00 PM  'B' 1 
    3 04:00 PM 00:00 AM  'C' 1 

对于周二

 4 08:01 AM 04:00 PM  'B' 2 
    5 07:00 PM 07:00 AM  'C' 2 

对于周三

 6 08:01 AM 04:00 PM  'A' 4 
    7 10:00 PM 08:00 AM  'B' 4 

这里几天都存储在位值的格式即

星期一= 1,星期二= 2,星期三= 4,星期四= 8,星期五= 16,星期六= 32,星期日= 64

当我们创建一个特定日子的时间表,它不应该在时间之间重叠。 我想获得一个SQL查询,用于在创建特定日期的新时间表时检查是否存在任何时间表。

对于特定事件时间(说甚至发生在周二周四上午04:00)我想找到开始和结束时间之间的正确时间表(将是“5”)。

+0

Anoop对于间隔表中的记录3,是第二天08:00的“最后一次”时间?所以应该是'1900-01-02 08:00'(基本上)?然后,你的**第二种情况是'set @end = dbo.TimeOnly('2011-may-12 08:30:00');' – 2011-05-11 14:22:15

+0

是的,这是第二天。 – 2011-05-11 14:30:33

+0

@Kit但我只检查第二个条件的时间部分所以这个函数返回'set @end = dbo.TimeOnly('2011-may-12 08:30:00');''1900-01-01 08 :30:00' – 2011-05-11 14:32:34

回答

0

改变你的选择将此:

select * from intervals where 
(
(dbo.TimeOnly(last) > dbo.TimeOnly(first) 
AND 
NOT (dbo.TimeOnly(last) < @start OR @end < dbo.TimeOnly(first))) 

OR 

(dbo.TimeOnly(last) < dbo.TimeOnly(first) 
AND 
(@start >= dbo.TimeOnly(first) OR @end <= dbo.TimeOnly(last) OR (@start < dbo.TimeOnly(first) AND @end > dbo.TimeOnly(last)))) 
) 

我可能已经错过了一个括号的地方,但我希望不会。

这里的概念是一个带有2个主要分组的OR查询。第一条检查间隔,其中最后>第一和主要是现有查询,并添加的最后>第一条件的副本,而第二条检查间隔,其中最后<第一

在的情况下最后<第一,有3种方式,一个间隔可以重叠:

  • 开始是之后的间隔的第一
  • 端是间隔的最后
  • 开始之前和彻底结束吞噬区间,即开始在第一个和结束在最后

这3个条件中的任何一个都意味着检查的时间表在一个exis中ting间隔,所以3个条件与ORs结合。

0

你需要做这样的事情:

Declare @start datetime 
Declare @duration int 

Set @start = dbo.TimeOnly('2011-May-11 07:01:00'); 
-- Get the number of minutes in your timespan 
Set @duration = DateDiff(minute, '2011-May-11 07:01:00', '2011-May-12 08:30:00'); 

Select id, first, last 
From intervals 
Where (DateDiff(minute, dbo.TimeOnly(first)), @start) + @duration) > 0 
AND DateDiff(minute, dbo.TimeOnly(first), @start) < 
DateDiff(minute, dbo.TimeOnly(first), dbo.TimeOnly(last)); 

假设你dbo.TimeOnly功能基本相同,Convert(time, {timefield})

这将首先找到新开始时间和现有开始时间之间的差异,然后将查明新时期的持续时间是否比该差异更长。这包括在现有项目之前或期间开始的新期间。

最后一项将新开始时间和现有开始时间之间的差异与现有时间段的持续时间进行比较,以检查现有时间段是否长于它们之间的差异。否则,新的开始时间自然会在现有结束时间之后,这意味着它不会重叠。