SQL 获取两个日期之间的酒店房间可用性

SQL Grabbing hotel room availability between two dates

如标​​题所述,我试图在用户指定入住和退房日期时获取所有可用的酒店房间。我取得了一些进展,但我很难理解这个过程背后的逻辑。

这是我的:

SELECT r.FLOOR, r.ROOM
FROM BOOKING b, ROOMS r
WHERE TO_DATE('2015-03-28', 'YYYY-MM-DD')
BETWEEN TO_DATE(b.CHECKIN, 'YY-MM-DD') AND TO_DATE(b.CHECKOUT, 'YY-MM-DD')
AND r.ROOMID = b.ROOMID;

这只是 returns 退回指定日期的所有房间。 (2015-03-28)

我如何更改此代码以接受两个日期、签到结帐,同时还提供可用房间而不是已租房间。

非常感谢任何帮助!

尝试获取所有房间的列表并从中排除已预订的房间,例如

SELECT r.FLOOR, r.ROOM
FROM ROOMS r
EXCEPT
SELECT r.FLOOR, r.ROOM
FROM BOOKING b, ROOMS r
WHERE TO_DATE('2015-03-28', 'YYYY-MM-DD')
BETWEEN TO_DATE(b.CHECKIN, 'YY-MM-DD') AND TO_DATE(b.CHECKOUT, 'YY-MM-DD')
AND r.ROOMID = b.ROOMID;

这可能更接近。适当替换参数(标有@):

SELECT r.FLOOR, r.ROOM
FROM ROOMS r
WHERE r.ROOMID NOT IN (
    -- exclude rooms where checkin or checkout overlaps with the desired dates
    SELECT r.ROOMID
    FROM BOOKING b
    WHERE (
            b.CHECKIN  BETWEEN TO_DATE(@CHECKIN, 'YY-MM-DD') AND TO_DATE(@CHECKOUT, 'YY-MM-DD')
        OR  b.CHECKOUT BETWEEN TO_DATE(@CHECKIN, 'YY-MM-DD') AND TO_DATE(@CHECKOUT, 'YY-MM-DD')
    )

您可以使用 Oracle 的 wm_overlaps 函数,它可以找到重叠的时间跨度:

select *
from rooms
where roomid not in 
(
  select b.room_id
  from booking b
  where wm_overlaps (
    wm_period(b.checkin, b.checkout),
    wm_period(
      to_date('2014-01-01', 'yyyy-mm-dd'), 
      to_date('2014-01-05', 'yyyy-mm-dd')
    )
  ) = 1
)

在此查询中,房间在给定的两个参数之间没有预订。