Как получить свободное время в списке бронируемых номеров, используя sql - PullRequest
1 голос
/ 17 мая 2019

Я работаю в базе данных и у меня возникла проблема при подсчете времени, доступного для бронирования номера в отеле

Мой стол выглядит как

Номер:

 _________________________________________________________________
| roomid  | roomname  | type      | time_start  | time_end        |
|_________|___________|___________|_____________|_________________|
|  R01    |  Room1    |     1     |  07:00      |    07:30        |
|_________|___________|___________|_____________|_________________|
|  R01    |  Room1    |     2     |  08:30      |    9:30         |
|_________|___________|___________|_____________|_________________|
|  R02    |  Room2     |   3      |  7:30       |   8:15          |    
|_________|___________|___________|_____________|_________________|
|  R02    |  Room2    |  4        |  10:15      |   11:20         |
|_________|___________|___________|_____________|_________________|

У меня есть время начала и продолжительность бронирования номера. Я хочу вернуть time_start и time_end, доступные пользователю, могут забронировать номер. Пример: я хочу запрос в базе данных и время выбора почти время ввода пользователя и продолжительность свободного времени должны> = 30. Пользователь хочет, чтобы бронирование началось с 8:00, а продолжительность бронирования - 30 минут. В моей базе данных вы можете видеть, что у меня есть две комнаты бронирования. Бронирование номера 01 7:00 -> 7: 30 и 8:30 -> 9:30 означает, что номер 1 доступен 7: 31 -> 8:29. Бронирование номера 02 7:30 -> 8:15 и 10:15 -> 11:20 это означает, что номер 1 доступен 8:16 -> 10: 14.

У меня есть возможность забронировать номер в двух комнатах:

1 . Room01:   7h31 -> 8:29

2. Room02: 8:16 -> 10:14

, поскольку условие заключается в том, что время бронирования наиболее близко к времени ввода пользователя, а время бронирования должно быть больше или равно 30. Это означает: Я выбираю room1, пользователь может бронировать, и я хочу, чтобы время возврата было доступно пользователю, который может бронировать (7h31 -> 8:29). Если пользователь бронирует номер в 5:00:00, но в моей таблице бронирования время начинается с 7:00:00 и заканчивается в 11:00:00, я хотел бы взять время бронирования пользователя, и время окончания будет 5:00:00. Мне бы хотелось, чтобы возвращаемый запрос был start_time: 5:00:00 и end_time: 5:30:00. Как мне это сделать?

Я пытаюсь написать sql код, похожий на

SELECT r.start_time, r.end_time
FROM rooms r
  INNER JOIN
  (
    SELECT room_id, r.time_start - r.end_time > :input_time)
    FROM r
    GROUP BY room_id
  ) r1
  ON b1.room_id = b.room_id

Но я думаю, что это не сработает.

У меня есть вопрос. Как вернуть доступные time_start и time_end, пользователь может забронировать номер с условием, что время бронирования ближе всего ко времени ввода пользователя, и время бронирования должно быть больше или равно 30, если у меня есть start_time и список номеров для бронирования. Если пользователь бронирует номер в 5:00:00, но в моей таблице бронирования время начинается с 7:00:00 и заканчивается в 11:00:00, я хотел бы взять время бронирования пользователя, и время окончания будет 5:00:00. Мне бы хотелось, чтобы возвращаемый запрос был time_start: 5:00:00 и time_end: 5:30:00. Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Если пользователь вводил раньше времени при бронировании номера?

0 голосов
/ 17 мая 2019

demo: db <> fiddle

Использование lag () оконная функция дает ожидаемый результат:

SELECT
    room_id,
    last_time + interval '1 minute' AS free_time_start,
    time_start - interval '1 minute' AS free_time_end
FROM (
    SELECT
        lag(time_end) OVER (PARTITION BY room_id ORDER BY time_start) AS last_time,
        *
    FROM
        rooms
) s
WHERE last_time < time_start

оконная функция позволяет получить значение из предыдущей записи (вы можете сгруппировать его по room_id с помощью предложения PARTITION BY и добавить определенный порядок).

Свободное время существует, если предыдущее время окончанияменьше текущего времени начала.


Добавление времени бронирования:

Вы можете взять время бронирования и проверить, соответствует ли оно расчетному свободному времени.После этого вы можете заказать по подходящим слотам и выдать только первый результат, используя LIMIT

SELECT
    free_time_start,
    free_time_end,
    booking_start BETWEEN free_time_start AND free_time_end
        AND 
    booking_end BETWEEN free_time_start AND free_time_end
FROM (
    SELECT
        room_id,
        last_time + interval '1 minute' AS free_time_start,
        time_start - interval '1 minute' AS free_time_end,
        '08:00'::time AS booking_start,
        '08:00'::time + interval '29 minutes' AS booking_end
    FROM (
        SELECT
            lag(time_end) OVER (PARTITION BY room_id ORDER BY time_start) AS last_time,
            *
        FROM
            rooms
    ) s
    WHERE last_time < time_start
) s
ORDER BY 3 DESC, 1
LIMIT 1

demo: db <> fiddle

...