MySQL - 查找可用的时间段

时间:2017-06-18 20:06:05

标签: mysql

我正在开发预订系统,用户可以预订不同服务期限的服务。

我已经有一个MySQL表存储预订,有可用时隙的表和返回空闲时间的查询。

我的bookings表格如下:

point_id     start (datetime)       end (datetime)
1            2017-06-17 14:50:00    2017-06-17 14:59:59
1            2017-06-17 15:10:00    2017-06-17 15:19:59
1            2017-06-17 15:40:00    2017-06-17 15:44:59
2            2017-06-17 15:50:00    2017-06-17 16:04:59
2            2017-06-17 16:05:00    2017-06-17 16:14:59
...

datetimes表包含10分钟的间隔:

datetime (datetime)
2017-06-17 14:40:00
2017-06-17 14:50:00
2017-06-17 15:00:00
2017-06-17 15:10:00
2017-06-17 15:20:00
2017-06-17 15:30:00
2017-06-17 15:40:00
...

以下是返回空闲时间段的查询:

SELECT
    a.datetime AS blockstart,
    DATE_ADD(a.datetime, INTERVAL 599 SECOND) AS blockend
FROM
    datetimes a
LEFT JOIN
    (
        SELECT *
        FROM bookings
        WHERE point_id = 1
    ) b ON
        (a.datetime BETWEEN b.start AND b.end)
        OR
        (DATE_ADD(a.datetime, INTERVAL 599 SECOND) BETWEEN b.start AND b.end)
WHERE b.id IS NULL AND a.datetime BETWEEN '2017-06-17 00:00:00' AND '2017-06-17 23:59:59';

如果服务时间少于25分钟 - 一切正常。 问题是持续时间超过25分钟的服务 - 我的查询返回的插槽重叠已经预订的10分钟服务。例如,我预订从13:00:00到13:09:59,如果我查询间隔1499秒它返回12:50:00,这将与下一个预订重叠。 任何人都可以帮我解决重叠服务的问题吗?

1 个答案:

答案 0 :(得分:1)

您可以找到无法使用的时段,然后使用日期时间表加入以查找可用的时段:

SELECT distinct all_slots.`datetime`
FROM datetimes AS all_slots
LEFT JOIN (
  SELECT `datetime`
  FROM datetimes AS d
  JOIN bookings AS b
    ON b.start BETWEEN d.`datetime` AND DATE_ADD(d.`datetime`, INTERVAL 599 SECOND)
    OR b.end   BETWEEN d.`datetime` AND DATE_ADD(d.`datetime`, INTERVAL 599 SECOND)
) AS not_available
ON all_slots.`datetime` = not_available.`datetime`
WHERE not_available.`datetime` is null