在mysql中的某个时间之后获取下一个可用的时隙

mqxuamgl  于 2021-06-15  发布在  Mysql
关注(0)|答案(2)|浏览(326)

我正试图通过检查表中的保留时间列表来获得下一个可用的时间段。每次预订至少可增加1小时,并可全天预订。例如,如果房间是从上午9点到上午10点,从上午12点到下午3点,我想在上午9点之后得到第一个空位。上午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

这是一张时间表

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');
2eafrhcq

2eafrhcq1#

您可以使用一个相关的子查询过滤掉紧跟在另一个子查询后面的保留;聚合的外部查询返回每个房间较早的可用时隙。

SELECT 
    roo.hotel_id,
    roo.room_id,
    roo.room_name,
    MIN(res.res_end) next_available_time
FROM 
    reservations res
    INNER JOINS rooms roo 
        ON  roo.hotel_id = res.hotel_id 
        AND roo.room_id  = res.room_id
WHERE 
    res.res_end > "2019-01-05 11:00:00"
    AND NOT EXISTS (
        SELECT 1 
        FROM reservations
        WHERE 
            res_start = res.res_end 
            AND hotel_id = res.hotel_id 
            AND room_id  = res.room_id
    ) 
GROUP BY 
    res.hotel_id,
    res.room_id,
    roo.room_name

在这把小提琴上测试过。
我假设两列 hotel_id 以及 room_id 连接表时使用的位置(如果 room_id 就足够了,这会稍微缩短查询)。

nhn9ugyo

nhn9ugyo2#

我想这个查询会给你你想要的结果。它查找比当前时间晚的任何预订 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

输出(对于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 在这个问题与你的兴趣时间。我已经在dbfiddle上更新了我的演示来演示查询,您可以调整 @time 变量来观察它的工作。

相关问题