【问题标题】:MySQL / PHP - Find available time slotsMySQL / PHP - 查找可用的时间段
【发布时间】:2012-11-05 01:44:22
【问题描述】:

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

我正在开发一个预订引擎,用户可以在其中在线预订某些服务。我一直在寻找和显示特定日期(或一周)内的可用时间段。我知道所需时段的长度(例如 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.

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

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

【问题讨论】:

  • 重叠的条件是什么?他们是为一个人预订服务,还是可以同时进行多个约会?
  • 这是一个人的预订。普通用户只能预订 100% 免费的时间段,即。没有重叠。管理员有一个不同/更复杂的日历,允许重叠(因为他们可能知道他们可以在某些情况下处理重叠)。对于上面的问题,我想唯一重要的一点是数据库表中可能存在重叠的插槽,系统应该在其中尝试查找可用性。

标签: php mysql datetime


【解决方案1】:
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-16 16:00:00 - 2012-11-17 12:00:00。而不是这个,我更喜欢包含时隙的许多行,例如:2012-11-16 16:00:00 - 2012-11-16 17:00:00 和 2012-11-16 17:00:00 - 2012 -11-16 18:00:00 等等...或者你会在以后使用 PHP 将整个空闲时间分成多个时段吗?
  • 还有一件事,我玩过你的解决方案,发现了一个我自己无法解决的棘手问题。如果我将您的语句与 start_of_search_window 2012-11-16 00:00:00 和 end_of_search_window 2012-11-18 00:00:00 一起使用,它将错过 2012-11-16 00:00:00 和 2012-11- 之间的空闲块16 日 13:00:00。 IE。它仅在找到第一个约会后从 free_from 开始。你能给我指出如何修复这个错误的正确方向吗?
  • 从概念上讲,这很简单 - 只需将 'bookings a' 表替换为包含在窗口开头结束的虚拟约会的 vierw - 但 SQL 相当复杂。
  • 可能是微不足道的,但我无法为此查询设置地板和天花板。
猜你喜欢
  • 2017-11-20
  • 2010-12-13
  • 1970-01-01
  • 2021-04-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-21
相关资源
最近更新 更多