找到两个日期之间的空时间块?

时间:2010-11-09 16:44:28

标签: php mysql

我有2个MySQL表,'scheduled_time'和'约会'

'scheduled_time'有2个DateTime字段,'start'和'end' - 这是我可以进行约会的时间范围。

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

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

假设我从2010年11月9日上午8点到下午2点开始'scheduled_time'。我有一个'预约'从早上8点到早上10点,一个从下午1点到下午2点。我怎样才能找到下一个可用的1小时块?

3 个答案:

答案 0 :(得分:3)

我刚才这样做了。我们有类似的结构:

  • 可用(包含员工的所有工作时间,灵活的工作时间)
  • 约会(与你的相似)

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

  • 获取员工的所有开始和结束日期时间< x&gt ;,按startdate排序
  • 让startAvailable =开始时间搜索(在你的情况下11/9/2010 @ 8am)
  • 让约会=约会列表中的第一次约会
  • 获取第一次约会的开始日期。如果它们之间的差异足够大,那就是你的块
  • 如果没有,请让startAvailable =约会的结束日期
  • 从列表中删除约会,让约会成为下一个约会
  • 重复检查可用块的过程

答案 1 :(得分:0)

首先,创建一个number table。这里的例子名为“Numbers”,列号为“number”。

然后你可以做类似

的事情
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]
    )

数字是我的Numbers表, chour 是一个定义为

的计算列
DATE_ADD('2010-11-08', INTERVAL number HOUR)

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

很抱歉,如果语法不完全正确,我会正常进行T-SQL: - )

编辑:这种技术仅适用于固定的时间块(小时只是一个例子,你可以轻松地做半小时),但在这种情况下它非常有效和可读。业务中的一个常见应用是映射日期,因为这是大多数合同所在的粒度,您可以使用少量表来覆盖很多天。

答案 2 :(得分: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表表示的一小时长的窗口表,并将结果与​​约会表连接,以查找没有已安排的内容的窗口。 / p>

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中的单个开始/结束范围中表示,预先创建日期日历并连接两个表等。