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

Я пытаюсь найти ответ на следующий запрос: клиент хочет одну комнату на три ночи подряд.Найдите первую доступную дату в декабре 2016 года.

Согласно вопросу, это должен быть правильный ответ.Но я не знаю, как ее решить.

+-----+------------+
| id  | MIN(i)     |
+-----+------------+
| 201 | 2016-12-11 |
+-----+------------+

Ссылка от вопрос № 14 здесь .

Это диаграмма ER базы данных:ER diagram of the database

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Это кажется очень трудным без календарного стола - потому что в соответствующем номере может не быть бронирования в течение месяца. Без какого-либо бронирования в этом месяце нет записей, с которых можно начинать.

select r.id, dte
from rooms r cross join
     (select date('2018-12-01') as dte union all
      select date('2018-12-02') as dte union all
      . . .
      select date('2018-12-32') as dte 
     ) d
where not exists (select 1 from bookings b where b.room_no = r.id and b.booking_date = d.dte) and
      not exists (select 1 from bookings b where b.room_no = r.id and b.booking_date = d.dte + interval 1 day) and
      not exists (select 1 from bookings b where b.room_no = r.id and b.booking_date = d.dte + interval 2 day)
order by d.dte
limit 1;

Предполагается, что booking_date - начало пребывания. Вы должны предоставить логику для «одной комнаты».

0 голосов
/ 22 января 2019
select distinct top 1 alll.i,alll.room_no,
case
when (select count(*) from booking where room_no = alll.room_no and booking_date between dateadd(day,1,alll.i) and dateadd(day,3,alll.i)) > 0  then 'Y'
else 'N'
end as av3
 from
(select c.i,b.room_no,b.booking_date
from calendar c cross join booking b
where month(c.i) = 12 and year(c.i) = 2016 and b.room_type_requested = 'single'
) as alll
join
(
select distinct c.i, b.room_no
from calendar c join booking b
on c.i between b.booking_date and DATEADD(day,b.nights-1,b.booking_date)
where month(c.i) = 12 and year(c.i) = 2016 and b.room_type_requested = 'single'
) as booked
on alll.i = booked.i
and alll.room_no <> booked.room_no
order by 1

Это работает. Это немного сложно, но в основном сначала проверяются все забронированные номера, а затем проводится сравнение номеров, не забронированных каждый день месяца, до следующих 3 дней.

0 голосов
/ 17 ноября 2018

Я прошу прощения за то, что немного устала от такого запроса, и я не могу гарантировать, что я правильно понял весь синтаксис, но я думаю, что что-то вроде следующего может работать:

SELECT id, DATE_ADD(b.booking_date, INTERVAL (end_date + 1 DAY) as date
FROM  (
         SELECT r.id, STR_TO_DATE('2016-01-01', '%Y-%m-%d') as start_of_month, b.booking_date as start_date, DATE_ADD(b.booking_date, INTERVAL (nights - 1) DAY) as end_date
         FROM room r
         LEFT JOIN booking b ON r.id = b.room_no
         ORDER BY r.id, b.booking_date
      ) as room_bookings
WHERE DATE_DIFF(room_bookings.start_of_month, room_bookings.start_date) >= 3
OR DATE_DIFF(room_bookings.end_date, (
         SELECT b2.booking_date FROM booking b2
         WHERE b2.room_no = room_bookings.id AND b2.booking_date > room_bookings.start_date
         ORDER BY b2.booking_date LIMIT 1)
      ) >= 3

На самом деле, теперь, когда я набираю все это, вы можете настроить WHERE основного запроса, чтобы вам даже не понадобился подвыбор room_bookings. Надеюсь, это поможет и не слишком далеко от цели.

...