2012-01-08 53 views
3

對於預訂系統,我有一個房間,到達和離開的表。尋找免費的房間(預訂系統)

示例數據:

id | room | arrival | departure 
---+------+------------+----------- 
1 | 1 | 2011-03-12 | 2011-03-14 
2 | 1 | 2011-03-08 | 2011-03-09 
3 | 1 | 2011-03-19 | 2011-03-20 
4 | 2 | 2011-03-22 | 2011-03-30 
5 | 2 | 2011-03-19 | 2011-03-22 

我的問題是現在:如果我有一個新的預訂(2011-03-102011-03-12),我怎麼能檢查哪些房間是免費的嗎?

該示例的輸出應該是空間12

+2

房間3,4和5似乎也可用。 ( - >你需要一張額外的桌子,基本上是現有房間的列表) – wildplasser 2012-01-08 18:03:06

+0

好吧,你是對的....我仍然有這張桌子 – user1137370 2012-01-08 18:07:18

回答

3

下面是一個查詢,將顯示NOT-免費客房約會跨度:

select room from bookings where 
(arrival<'2011-03-12' and departure>='2011-03-12') -- overlap at the end 
OR (arrival<='2011-03-10' and departure>'2011-03-10') -- overlap at the start 
OR (arrival>='2011-03-10' and departure<='2011-03-12') -- complete overlap 

您可以使用此與

select roomnumber from rooms where roomnumber not in (... as above ...) 

找到免費客房

+0

完美...非常好:)我剛添加DISTINCT到第一個語句 – user1137370 2012-01-08 18:23:34

+0

這可以擴展爲選擇數量(*)作爲數量,房間從預訂...按房間分組:這種方式會告訴你碰撞的數量 - 如果你的酒店相當滿,少量的碰撞可能會導致有可能脫離房間互換。 (只在你的DISTINCT上頭腦風暴) – 2012-01-08 18:30:20

+0

我有一個非常類似的問題,並提出你的解決方案。正在尋找其他的想法,然後當我看到你的答案時笑了起來。到底我在做什麼。酷:D – 2015-03-20 00:02:36

1

你也可以使用BETWEEN比較運算符來實現此目的。在這種情況下,你會這樣做:

SELECT r.id FROM room r WHERE r.id NOT IN 
(
    SELECT rb.room FROM room_booking rb WHERE 
     ('2011-03-10' BETWEEN rb.arrival AND rb.departure) OR 
     ('2011-03-12' BETWEEN rb.arrival AND rb.departure) 
) 
+0

我更喜歡BETWEEN。在這種情況下閱讀起來更容易。 – netcoder 2012-01-08 18:27:06

+2

這個查詢將檢測到完整的重疊:如果2011-03-10到2011-03-12預定了一個房間,那麼2011-03-08到2011-03-14的查詢將顯示房間爲空閒,即你只能改變開始和結束的重疊,但不能完成重疊。 – 2012-01-08 18:32:55

+0

但的確如此,我會這樣做:'('2011-03-10'+ INTERVAL 1天)抵達和出發之間和('2011年3月12日 - 間隔1天)到達和離開之間「 – netcoder 2012-01-08 18:35:33