SQL - Найти бесплатные слоты для системы бронирования - PullRequest
0 голосов
/ 10 октября 2018

Я получил простой 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 года.

Как я могу это сделать?Я действительно не понимаю.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Сначала давайте посмотрим пустые интервалы на комнату:

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 ed с интервалом между now() и StartTime самого первого элемента.Таким образом, у вас будет результат, из которого вы сможете получить ответы на свои вопросы.Я не собираюсь реализовывать решение для вашей домашней работы, этот ответ должен послужить отправной точкой для решения.

0 голосов
/ 10 октября 2018
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 |
+------+-------------------+

Но ваш реальный вопрос, похоже, таков:

Какие комнаты имеют 3-месячныйдоступность »в течение 45 дней, начиная с 1 октября.Это немного другая (и я думаю, более сложная) проблема.

0 голосов
/ 10 октября 2018

Я предполагаю, что у вас есть какая-то таблица 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
...