2010-11-09 41 views
3

我有2个MySQL表''scheduled_time'和'约会'查找两个日期之间的空时间块?

'scheduled_time'有2个日期时间字段,'开始'和'结束' - 这是一个时间范围,当我可用于约会。

'约会'包含约会细节,但也是'开始'和'结束'字段,这最终将在'scheduled_time'中指定的范围内。

当我考虑到两个表时,找到空时间块的最佳方式是什么?

可以说我有'scheduled_time'从11月9日开始,从上午8点到下午2点。我从上午8点到上午10点,下午1点到2点有一个'预约'。我如何才能找到下一个可用的说1小时的区块?

+0

我今晚要回答这个问题,如果没有人回答你然后 – 2010-11-09 16:58:59

+0

我很好奇,知道是否有一个“简单”的方法来做到这一点... – 2010-11-09 17:02:41

回答

3

我之前做过这个。我们也有类似的结构:

  • 有(包含一个员工的所有工作时间,弹性工作时间)
  • 约会(类似于你)

我所做的基本上是这样(步骤) :

  • 获取所有的开始和结束日期时间为员工< X>,由开始日期排序
  • 让启动可用=开始时间搜索(在您的情况下11/9/2010 @ 8am)
  • 让约会=约会列表中的第一个约会
  • 获取第一个约会的开始日期。如果它们之间的差异足够大,有你的块
  • 如果没有,让startAvailable =任命的结束日期
  • 删除约会从列表中,让约会成为下一个约会
  • 重复检查可用的过程块
+0

我喜欢这个答案,在我看来,这是非常简单的实施。其他两个似乎也可以工作,但SQL连接不是我的朋友。 – Romulo 2010-11-10 03:26:50

0

首先,创建一个number table。这里作为例子命名为“数字”,并带有“数字”列。

然后,你可以这样做

select chour as [Free Hour] from Numbers n 
inner join Scheduled s on n.chour >= s.start and n.chour < s.[end] 
where chour not in 
    (
    select chour from Numbers n 
    inner join Appointments a ON n.chour >= q.start and n.chour < a.[end] 
    ) 

是我的号码表,chour是被定义为

DATE_ADD('2010-11-08', INTERVAL number HOUR) 

计算列,您也可以将其存储为一个持久列当然。

对不起,如果语法不完全正确,我做的T-SQL正常:-)

编辑:此方法仅适用于在固定的时间块(小时仅仅是一个例子,你可以做一半小时也一样容易),但在这种情况下它非常高效且易读。业务中的常用应用是映射日期,因为这是大多数合约所在的粒度,您可以使用少量表格覆盖很多天。

0

这是一个很好的地方使用一个虚拟整数表,它可以帮助你create data from nothing。这里有一个例子:

create table ints(i tinyint); 
insert into ints values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 

然后,您可以使用此表中的一些交叉连接产生的由您SCHEDULED_TIME表来表示长达一小时的窗口表,并留下连接的结果对任命表中查找窗口没有已经预定的东西。

SELECT 
h.HourWindowStart, h.HourWindowEnd 
FROM (
    SELECT 
    s.start + INTERVAL t.i*100 + u.i*10 + v.i HOUR AS HourWindowStart, 
    s.start + INTERVAL t.i*100 + u.i*10 + v.i + 1 HOUR AS HourWindowEnd 
    FROM scheduled_time s 
    JOIN ints AS t 
    JOIN ints AS u 
    JOIN ints AS v 
    WHERE s.start + INTERVAL t.i*100 + u.i*10 + v.i HOUR < s.end 
    ORDER BY HourWindowStart 
) as h 
LEFT JOIN appointments a ON a.end > h.HourWindowStart AND a.start < h.HourWindowEnd 
WHERE a.start IS NULL 

可以调整此处理,以计算更大/更小的可用性窗口的各个部分(由半小时,按天,等等),使用基于的最大数目更多或更少的交叉连接的整数表的的可用性窗口,可以在scheduled_time的单个开始/结束范围内表示,预先创建日期日历并加入两个表格等。

相关问题