0

我为已预订的房间准备了一个简单的 mysql 表。这里的sql结构:

CREATE TABLE Rooms (
   `ID` int, `Description` varchar(50)
);

INSERT INTO Rooms values
(123, 'Room in Frankfurt'),
(234, 'Room in Wiesbaden'),
(245, 'Room in Darmstadt');

CREATE TABLE Bookings (
   `ID` int, `StartTime` datetime, `EndTime` datetime, `post_ID` int
);

INSERT INTO Bookings
    (`ID`, `StartTime`, `EndTime`, `post_ID`)
VALUES
    (1, '2018-01-05', '2018-04-05', 123),
    (2, '2018-08-01', '2018-10-01', 123),
    (3, '2019-02-01', '2019-06-01', 123),
    (4, '2018-02-01', '2018-06-01', 234),
    (5, '2018-08-01', '2018-09-01', 294),
    (6, '2018-09-01', '2018-11-30', 234),
    (7, '2018-11-01', '2018-12-30', 294)
;

在这张表中,我们可以看到我们拥有的所有房间的所有预订。我的问题是找到一个 SQL 查询来找到一个房间的空闲插槽。用户可以给出这些参数:

  • 最早入住日期(例如:2018-10-01)
  • 最近签到的日期(例如:2018-10-15)
  • 以月为单位的最长期限(例如:3 个月)

所以用户需要3个月的房间,从01-15开始。2018 年 10 月。

我怎样才能做到这一点?我真的不明白。

谢谢!

4

3 回答 3

1

我假设你有某种Rooms桌子

http://sqlfiddle.com/#!9/fe977/1

SELECT r.*
FROM rooms r
LEFT JOIN Bookings b
ON r.id = b.post_id
   AND (
     (b.StartTime <= '2018-10-01'
   AND b.EndTime >= '2018-10-01')
     OR
     (b.StartTime >= '2018-10-01'
   AND b.StartTime <= '2018-10-15')
   )     
WHERE b.id IS NULL

更新我仍然不确定我是否有你的目标。但这是另一种方法。如果您希望开始日期灵活,我建议您calendar为一年中的所有日期设置表格。这将允许在您运行查询时避免不必要的计算。

这是一个小提琴:http ://sqlfiddle.com/#!9/29926/3

SELECT r.*,
c.date
FROM rooms r
LEFT JOIN calendar c
ON c.date BETWEEN '2018-10-01' AND '2018-10-15'
LEFT JOIN Bookings b
ON r.id = b.post_id
   AND (
     (b.StartTime <= c.date
   AND b.EndTime >= c.date)
     OR
     (b.StartTime >= c.date
   AND b.StartTime <= (c.date + INTERVAL 3 MONTH))
   )     
WHERE b.id IS NULL

更新 2结合@Strawberry 答案我想我们可以将查询修改为:

http://sqlfiddle.com/#!9/29926/5

SELECT r.*,
c.date
FROM rooms r
LEFT JOIN calendar c
ON c.date BETWEEN '2018-10-01' AND '2018-10-15'
LEFT JOIN Bookings b
ON r.id = b.post_id
   AND b.StartTime <= (c.date + INTERVAL 3 MONTH)
   AND b.EndTime >= c.date     
WHERE b.id IS NULL
于 2018-10-10T12:39:53.997 回答
0

首先,让我们看看每个房间的空区间:

select room_ID, a.EndTime, b.StartTime
from Bookings a
join (select c.StartTime
      from Bookings c
      where c.room_ID = a.room_ID and 
      not exists (select 1
                  from Bookings d
                  where d.room_ID = c.room_ID and d.StartTime > a.EndTime and d.StartTime < c.StartTime)) b;

这应该与第一个元素union之间的间隔now()和。StartTime这样,您将获得一个结果,您可以从中得出问题的答案。我不打算为您的作业实施解决方案,这个答案旨在成为解决方案的起点。

于 2018-10-10T13:34:43.817 回答
0
Supplied criteria:

     1.  a date for the earliest check-in (ex: 2018-10-01)
     2.  a date for the latest check-in (ex: 2018-10-15)
     3.  a maximum period in months (example: 3 months)

这是一个仅考虑标准 1 和 3 的解决方案......

SELECT r.*
  FROM rooms r
  LEFT 
  JOIN bookings b
    ON b.post_id = r.id
   AND b.starttime < '2018-10-01' + INTERVAL 3 MONTH
   AND b.endtime > '2018-10-01'
 WHERE b.id IS NULL;
+------+-------------------+
| ID   | Description       |
+------+-------------------+
|  123 | Room in Frankfurt |
|  245 | Room in Darmstadt |
+------+-------------------+

但你真正的问题似乎是:

从 10 月 1 日开始的 45 天内,哪些房间有“3 个月的空房”。这是一个稍微不同(我认为更复杂)的问题。

于 2018-10-10T13:42:05.727 回答