mysql - 获得 1 小时的房间可用性增量 MySQL

标签 mysql sql join

我正在尝试以 1 小时为增量获取我酒店的房间可用性。因此,例如,如果房间是从上午 9 点到上午 10 点以及从中午 12 点到下午 3 点预订的,我试图获取 available_from 到 available_to 之间所有其他时间的 1 小时增量

我可以在 table 上离开加入并获得房间可用性,但不能获得时间段。

这是我的相关架构:

酒店:

Id | name

预订:

Id | hotel_id | room_id | start | end | status

房间:

Id | hotel_id | name | number | available_from | available_to

这是我目前的查询:

SELECT r.id, r.name, r.number, r.type, r.rating
FROM rooms r
    LEFT OUTER JOIN reservations res ON res.room_id = r.id 
        AND CURRENT_TIMESTAMP BETWEEN r.available_from AND r.available_to
GROUP BY r.id, r.type

示例:

(这是我试图从数据库中取回的数组。忽略属性名称):

[{"roomNumber":1,"availableTimes":["2019-01-01 00:00:00","2019-01-01 01:00:00","2019-01-01 02:00:00","2019-01-01 03:00:00","2019-01-01 04:00:00","2019-01-01 05:00:00","2019-01-01 06:00:00","2019-01-01 07:00:00","2019-01-01 08:00:00","2019-01-01 09:00:00","2019-01-01 10:00:00","2019-01-01 11:00:00","2019-01-01 12:00:00","2019-01-01 13:00:00","2019-01-01 14:00:00","2019-01-01 15:00:00","2019-01-01 16:00:00","2019-01-01 17:00:00","2019-01-01 18:00:00","2019-01-01 19:00:00","2019-01-01 20:00:00","2019-01-01 21:00:00","2019-01-01 22:00:00","2019-01-01 23:00:00"]}]

我尝试了以下方法:

SELECT free_from, free_until
FROM (
  SELECT a.end AS free_from,
  (SELECT MIN(c.start)
   FROM reservations c
   WHERE c.start > a.end) as free_until
  FROM reservations a
  WHERE NOT EXISTS (
    SELECT 1
    FROM reservations b
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL 1 HOUR
  )
  AND a.end BETWEEN '2019-01-03 09:00' AND '2019-01-03 21:00'
) as d
ORDER BY free_until-free_from
LIMIT 0,3;

但是我得到的一行只返回了 1 个结果,这也是不正确的。我该如何解决这个问题?

示例数据:

酒店:

1 | Marriott

预订:

1 | 1 | 1 | 2019-01-03 15:00:00 | 2019-01-03 17:00:00 | Confirmed
1 | 1 | 1 | 2019-01-03 18:00:00 | 2019-01-03 20:00:00 | Confirmed

房间:

1 | 1 | "Single" | 528 | 09:00:00 | 21:00:00

预期结果

房间编号 |房间名称 |可用时间

1 | "Single" | 2019-01-03 09:00:00, 2019-01-03 10:00:00, 2019-01-03 11:00:00, 2019-01-03 12:00:00, 2019-01-03 13:00:00, 2019-01-03 14:00:00, 2019-01-03 17:00:00, 2019-01-03 20:00:00, 2019-01-03 21:00:00, 2019-01-03 22:00:00, 2019-01-03 23:00:00, 2019-01-03 24:00:00

最佳答案

如果您将 Times_Slots 表添加到您的数据库中,如 SQL Fiddle 所示:

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

然后以下查询将提供所有已预订房间的空房情况:

查询 1:

select r.id
     , r.Name
     , res_date + interval t.slot hour_second available
  from Time_Slots t
  join Rooms r
    on t.Slot between r.available_from and r.available_to
  join (select distinct room_id, date(start) res_date from Reservation) res
    on res.room_id = r.id
 where (r.id, res_date + interval t.slot hour_second) not in (
        select r.room_id
             , date(r.start) + interval t.slot hour_second Reserved
          from Time_Slots t
          join Reservation r
            on r.start <= date(r.end) + interval t.slot hour_second
           and date(r.start) + interval t.slot hour_second < r.end)

此查询的工作原理是,首先从 Times_Slots 中为至少有一个房间预订的每一天选择可用时段,然后过滤掉预订的时段。

Results :

| id |   Name |            available |
|----|--------|----------------------|
|  1 | Single | 2019-01-03T09:00:00Z |
|  1 | Single | 2019-01-03T10:00:00Z |
|  1 | Single | 2019-01-03T11:00:00Z |
|  1 | Single | 2019-01-03T12:00:00Z |
|  1 | Single | 2019-01-03T13:00:00Z |
|  1 | Single | 2019-01-03T14:00:00Z |
|  1 | Single | 2019-01-03T17:00:00Z |
|  1 | Single | 2019-01-03T20:00:00Z |
|  1 | Single | 2019-01-03T21:00:00Z |

在您的示例输出中,您指出房间可用于 2019-01-03 22:00:00、2019-01-03 23:00:00、2019-01-03 24:00:00,但是那些时间在房间表定义的可用性 block 之后,因此我的查询排除了那些时间。

关于mysql - 获得 1 小时的房间可用性增量 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53989112/

相关文章:

mysql - 更改整个数据库中的数据类型

mysql - 如何使用从 MySQL 中提取逗号分隔值的连接

mysql选择两列中具有相同值的所有行

java - JPA + Hibernate 中的日期前缀自动递增 id

mysql - SQL DELETE with JOIN another table for WHERE 条件

php - 多个 Inner Join 删除属性

mysql - 在 NodeJS 中 Sequelize : Inner JOIN implementation Failure

mysql - 计算型 SQL 查询中的多对多关系表引用 - App Maker

mysql - 在表正则表达式中查找行 - mysql

mysql - 在几个条件下计算总数