在MySQL中一定时间后获取下一个可用时隙

时间:2019-01-06 00:51:17

标签: mysql sql database mysqli relational-database

我正在通过检查表中的保留时间列表来获取下一个可用时隙。每个预约可以最少增加1小时,并且可以全天候进行。因此,例如,如果房间是从9 AM到10 AM,从12 AM到3 PM预订的,我想在9 AM之后获得第一个空位。现在是上午10点。

我可以离开桌子,获得房间的可用性,但不提供时隙。

这是我的相关架构:

预订

res_id | hotel_id | room_id | res_start | res_end

房间:

room_id | hotel_id | room_name | room_number

这是我到目前为止的查询:

SELECT free_from, free_until
FROM (
  SELECT a.res_end AS free_from,
  (SELECT MIN(c.res_start)
   FROM reservations c
   WHERE c.res_start > a.res_end) as free_until
   and b.res_end > "2019-01-05 11:00:00"
  FROM reservations a
  WHERE NOT EXISTS (
    SELECT 1
    FROM reservations b
    WHERE b.res_start > a.res_end
  )
) as d
ORDER BY free_until-free_from

但是我得到的返回的时间不正确。

预期结果:

room_id | room_name | Next available time
1       | "Single"  | 2019-01-05 10:00:00

这是一个timeslots表

CREATE TABLE time_slots
    (`slot` time);

INSERT INTO time_slots
    (`slot`)
VALUES
    ('00:00:00'),
    ('01:00:00'),
    ('02:00:00'),
    ('03:00:00'),
    ('04:00:00'),
    ('05:00:00'),
    ('06:00:00'),
    ('07:00:00'),
    ('08:00:00'),
    ('09:00:00'),
    ('10:00:00'),
    ('11:00:00'),
    ('12:00:00'),
    ('13:00:00'),
    ('14:00:00'),
    ('15:00:00'),
    ('16:00:00'),
    ('17:00:00'),
    ('18:00:00'),
    ('19:00:00'),
    ('20:00:00'),
    ('21:00:00'),
    ('22:00:00'),
    ('23:00:00');

2 个答案:

答案 0 :(得分:1)

您可以使用相关子查询来筛选出紧跟在另一个之后的预订;汇总的外部查询返回每个房间的早期可用时隙。

hotel_id

this DB fiddle中进行了测试。

我假设在连接表时要同时使用room_idroom_id这两个列(如果{{1}}就足够了,那会稍微缩短查询时间)。

答案 1 :(得分:1)

我认为此查询将为您提供所需的结果。它会查找比当前时间晚res_end与另一个预订都不匹配的res_start的任何预订。

SELECT rm.room_id, rm.room_name, MIN(re.res_end) AS `available from`
FROM reservations re
LEFT JOIN reservations rs ON rs.hotel_id = re.hotel_id AND rs.room_id = re.room_id AND rs.res_start = re.res_end
JOIN rooms rm ON rm.hotel_id = re.hotel_id
WHERE rs.res_id IS NULL AND re.res_end > NOW()
GROUP BY rm.room_id, rm.room_name

输出(对于我的小demo on dbfiddle):

room_id     room_name   available from
1           Single      2019-01-06 10:00

更新

此查询使用一个时隙表来考虑当感兴趣的时间开始时房间中没有预订的情况:

SELECT rm.room_id, rm.room_name,
       MIN(t.slot) AS `available from`
FROM time_slots t
CROSS JOIN rooms rm
LEFT JOIN reservations r ON HOUR(t.slot) BETWEEN HOUR(r.res_start) AND HOUR(r.res_end) - 1 
                        AND DATE(r.res_start) = DATE(@time)
                        AND r.hotel_id = rm.hotel_id
                        AND r.room_id  = rm.room_id
WHERE t.slot > @time AND r.res_id IS NULL
GROUP BY rm.room_id, rm.room_name
ORDER BY rm.room_id

您可以将查询中的@time替换为您感兴趣的时间。我已经更新了demo on dbfiddle来演示查询,您可以通过调整@time变量来观看它的运行。