我正在开发预订系统,用户可以预订不同服务期限的服务。
我已经有一个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,这将与下一个预订重叠。 任何人都可以帮我解决重叠服务的问题吗?
答案 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