5

有人就类似主题提出了一些问题,但我找不到解决这个特定问题的方法,并感谢您的意见。

我正在开发一个预订引擎,用户可以在其中在线预订某些服务。我一直在寻找和显示特定日期(或一周)内的可用时间段。我知道所需时段的长度(例如 1 小时)和可预订时段的营业时间(例如 09:00 - 18:00)。此外,我有一个 MySQL 表来存储已经存在的约会。与我的问题相关的列如下所示:

id  start (datetime)        end (datetime)
1   '2012-11-16 13:00:00'   '2012-11-16 14:30:00'
2   '2012-11-16 15:00:00'   '2012-11-16 16:00:00'
3   '2012-11-17 12:00:00'   '2012-11-16 15:45:00'
4   '2012-11-17 13:00:00'   '2012-11-16 16:15:00'
...

现在鉴于上述信息,我无法找到一个好的解决方案(在 MySQL 或 PHP 中)来检索可用时隙列表。还有一个条件:时隙只能以季度为单位开始。IE。对于上面 16 日可用一小时时段的示例数据,将是:
09:00、09:15、09:30、09:45、10:00、...、12:00、16:00、16: 15,...,17:00。

请注意,即使可能存在重叠时间(如示例数据中所示),可用时隙也不能重叠。

您认为解决此问题的最佳方法是什么?

4

1 回答 1

8
SELECT a.end AS free_after
FROM bookings a
WHERE NOT EXISTS (
  SELECT 1
  FROM bookings b
  WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOURS
)
AND a.end BETWEEN start_of_search_window AND end_of_search_window;

您只需要提供your_duration(整数)、start_of_search_window(日期时间)和end_of_search_window(日期时间)的值。

如果你想要花里胡哨....

SELECT free_from, free_until
FROM (
  SELECT a.end AS free_from,
  (SELECT MIN(c.start)
   FROM bookings c
   WHERE c.start > a.end) as free_until
  FROM bookings a
  WHERE NOT EXISTS (
    SELECT 1
    FROM bookings b
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOUR
  )
  AND a.end BETWEEN start_of_search_window AND end_of_search_window
)
ORDER BY free_until-free_from
LIMIT 0,3;

将为您提供窗口内三个最短的可用插槽(即最接近目标大小)。

于 2012-11-16T14:22:52.757 回答