2016-05-15 89 views
2

我有以下表格:MySQL查詢與左連接和時間條件

mysql> select * from room; 
+----+----------+ 
| ID | NAME  | 
+----+----------+ 
| 1 | Room 101 | 
| 2 | Room 102 | 
| 3 | Room 103 | 
+----+----------+ 


mysql> select * from booking; 
+---------+---------------------+---------------------+----------------+ 
| ROOM_ID | START    | END     | GUEST   | 
+---------+---------------------+---------------------+----------------+ 
|  1 | 2016-04-01 00:00:00 | 2016-04-30 00:00:00 | Dorian Gray | 
|  1 | 2016-05-03 00:00:00 | 2016-05-20 00:00:00 | Vanessa Ives | 
|  1 | 2016-05-21 00:00:00 | 2016-05-30 00:00:00 | Ethan Chandler | 
|  2 | 2016-05-06 00:00:00 | 2016-05-18 00:00:00 | John Clare  | 
+---------+---------------------+---------------------+----------------+ 

對於每一個房間,我想獲得有關其預訂狀態的附加信息。如果預訂,我想顯示預訂狀態。如果沒有預訂,則必須顯示NULL

如果我開始一個基本的查詢..

mysql> select * from room r, booking b where r.id = b.room_id; 
+----+----------+---------+---------------------+---------------------+----------------+ 
| ID | NAME  | ROOM_ID | START    | END     | GUEST   | 
+----+----------+---------+---------------------+---------------------+----------------+ 
| 1 | Room 101 |  1 | 2016-04-01 00:00:00 | 2016-04-30 00:00:00 | Dorian Gray | 
| 1 | Room 101 |  1 | 2016-05-03 00:00:00 | 2016-05-20 00:00:00 | Vanessa Ives | 
| 1 | Room 101 |  1 | 2016-05-21 00:00:00 | 2016-05-30 00:00:00 | Ethan Chandler | 
| 2 | Room 102 |  2 | 2016-05-06 00:00:00 | 2016-05-18 00:00:00 | John Clare  | 
+----+----------+---------+---------------------+---------------------+----------------+ 

它工作正常,但是這不是我想要的..讓我們看看還剩加入...

mysql> select * from room r left join booking b on r.id = b.room_id; 
+----+----------+---------+---------------------+---------------------+----------------+ 
| ID | NAME  | ROOM_ID | START    | END     | GUEST   | 
+----+----------+---------+---------------------+---------------------+----------------+ 
| 1 | Room 101 |  1 | 2016-04-01 00:00:00 | 2016-04-30 00:00:00 | Dorian Gray | 
| 1 | Room 101 |  1 | 2016-05-03 00:00:00 | 2016-05-20 00:00:00 | Vanessa Ives | 
| 1 | Room 101 |  1 | 2016-05-21 00:00:00 | 2016-05-30 00:00:00 | Ethan Chandler | 
| 2 | Room 102 |  2 | 2016-05-06 00:00:00 | 2016-05-18 00:00:00 | John Clare  | 
| 3 | Room 103 | NULL | NULL    | NULL    | NULL   | 
+----+----------+---------+---------------------+---------------------+----------------+ 

儘管如此,顯示重複的......讓我們嘗試與多個條件:

mysql> select * from room r left join booking b on r.id = b.room_id where b.start<now() and b.end>now(); 
+----+----------+---------+---------------------+---------------------+--------------+ 
| ID | NAME  | ROOM_ID | START    | END     | GUEST  | 
+----+----------+---------+---------------------+---------------------+--------------+ 
| 1 | Room 101 |  1 | 2016-05-03 00:00:00 | 2016-05-20 00:00:00 | Vanessa Ives | 
| 2 | Room 102 |  2 | 2016-05-06 00:00:00 | 2016-05-18 00:00:00 | John Clare | 
+----+----------+---------+---------------------+---------------------+--------------+ 

好吧......但是錯了,因爲「103室」不顯示(這不是預訂).. 。

我希望得到的東西是這樣的:

+----+----------+---------+---------------------+---------------------+--------------+ 
| ID | NAME  | ROOM_ID | START    | END     | GUEST  | 
+----+----------+---------+---------------------+---------------------+--------------+ 
| 1 | Room 101 |  1 | 2016-05-03 00:00:00 | 2016-05-20 00:00:00 | Vanessa Ives | 
| 2 | Room 102 |  2 | 2016-05-06 00:00:00 | 2016-05-18 00:00:00 | John Clare | 
| 3 | Room 103 | NULL | NULL    | NULL    | NULL   | 
+----+----------+---------+---------------------+---------------------+--------------+ 

任何想法?

+0

有沒有sqlfiddle? – Strawberry

+0

我剛剛創建了一個:) http://sqlfiddle.com/#!9/52b53 – hosselausso

回答

2

我不明白爲什麼您使用的是日期時間存儲日期......但無論如何...

SELECT * 
    FROM room r 
    LEFT 
    JOIN booking b 
    ON b.room_id = r.id 
    AND CURDATE() BETWEEN b.start AND b.end; 
+0

我使用日期時間,因爲原始問題也包含時間......但您是對的。這工作!謝謝! :) – hosselausso

+0

爲了使它有點複雜,如果名稱是指向另一個表「用戶」的ID呢? http://sqlfiddle.com/#!9/33b2d3/2 – hosselausso

+0

這只是另一個加入 – Strawberry

0

下面的查詢應該給你你正在尋找的結果。 SELECT * FROM room r will give you every room number and SELECT * FROM booking b WHERE CURDATE()BETWEEN b.start AND b.end將爲您提供在START和END日期內包含當天日期的記錄。然後你會LEFT JOIN主查詢與子查詢ON r.id = b.room_id

SELECT * FROM room r LEFT JOIN 
(SELECT * FROM booking b WHERE CURDATE() BETWEEN b.start AND b.end) b ON r.id = b.room_id; 
+0

是的,這似乎也工作:)與上述答案相比,這將有什麼優勢(沒有選擇內選擇)? – hosselausso

+0

@hosselausso這很簡單。這與其他答案沒有任何優勢。要明白爲什麼,請按照以下步驟操作:1.添加一個PRIMARY KEY進行預訂(room_id,start)。 2.爲每個表添加幾十行。 3.比較兩個查詢的性能。 4.對兩個查詢運行EXPLAIN。我會堅持我的脖子出來,並說,a)我的答案會比上面的答案更好地利用索引,b)中間結果中將返回更少的行,並且c)我的查詢將執行(略微)總體更快。 – Strawberry

+0

@Strawberry你的回答比我的好。我發佈了我的答案,因爲你張貼你的。只要我看到你的帖子,我就給你+1。 – josemr