簡體   English   中英

如何查詢酒店數據庫以返回連續三晚可用單間的查詢?

[英]How to query a hotel database to return the query for a single room available for three consecutive nights?

我試圖找到以下查詢的答案:一位客戶想要一個連續三晚的單人房。 查找 2016 年 12 月的第一個可用日期。

根據問題,這應該是正確的答案。 但我不知道如何解決它。

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

該鏈接來自此處的第 14 個問題

這是數據庫的ER圖:數據庫的ER圖

我很抱歉,我對這種查詢有點生疏,我不能保證我的所有語法都是正確的,但我認為以下內容可能有效:

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 子選擇。 希望這會有所幫助,並且不會太離譜。

如果沒有日歷表,這似乎很難做到——因為合適的房間在一個月內可能根本沒有預訂。 沒有任何預訂,當月開始沒有記錄。

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是停留的開始。 您需要為“單人間”提供邏輯。

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 天都沒有預訂的房間。

我的解決方案是將問題分成 2 部分(最后是 2 個查詢連接在一起)。 可能不是最有效的,但解決方案是正確的。

1) 在單人間中,查看最后退房日期,然后查看哪個是空置的(即本月剩余時間沒有更多預訂) 2) 在當前預訂之間辦理入住 - 看看是否有 3 天它們之間的差距 3) 將它們結合在一起 - 抓住最小

WITH subquery AS( -- existing single-bed bookings in Dec 
SELECT room_no, booking_date, 
        DATE_ADD(booking_date, INTERVAL (nights-1) DAY) AS last_night
   FROM booking
   WHERE room_type_requested='single' AND
         DATE_ADD(booking_date, INTERVAL (nights-1) DAY)>='2016-12-1' AND 
         booking_date <='2016-12-31'
   ORDER BY room_no, last_night) 

SELECT room_no, MIN(first_avail) AS first_avail --3) join the 2 together
FROM( 

-- 1) check the last date the room is booked in December (available after)

SELECT room_no, MIN(first_avail) AS first_avail
  FROM(
      SELECT room_no, DATE_ADD(MAX(last_night), INTERVAL 1 DAY) AS first_avail
        FROM subquery q3
        GROUP BY 1
        ORDER BY 2) AS t2

UNION 

-- 2) check if any 3-day exist in between reservations 

SELECT room_no, DATE_ADD(MIN(end2), INTERVAL 1 DAY) AS first_avail
  FROM(
      SELECT q1.booking_date AS beg1, q1.room_no, q1.last_night AS end1, 
             q2.booking_date AS beg2, q2.last_night AS end2
        FROM subquery q1
        JOIN subquery q2 
          ON q1.room_no = q2.room_no AND q2.booking_date > q1.last_night
      GROUP BY 2,1
      ORDER BY 2,1) AS t
      WHERE beg2-end1 > 3) AS inner_t

這在概念上是有效的,因為第一個可用日期應該始終是上一次預訂的結束日期。

SELECT MIN(DATE_ADD(a.booking_date, INTERVAL nights DAY)) AS i
FROM booking AS a
WHERE DATE_ADD(a.booking_date, INTERVAL nights DAY)
      >= '2016-12-01'
      AND room_type_requested = 'single'
      AND NOT EXISTS
      (SELECT 1 FROM booking AS b
        WHERE b.booking_date BETWEEN
        DATE_ADD(a.booking_date, INTERVAL nights DAY) 
        AND DATE_ADD(a.booking_date, INTERVAL nights+2 DAY)
        AND a.room_no = b.room_no)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM