2014-02-07 43 views
2

我有2個表 - reservation返回行,如果值不存在

id | some_other_column 
    ----+------------------ 
    1 | value 
    2 | value 
    3 | value 

而第二個表 - reservation_log

id | reservation_id | change_type 
    ----+----------------+------------- 
    1 | 1    | create 
    2 | 2    | create 
    3 | 3    | create 
    4 | 1    | cancel 
    5 | 2    | cancel 

,我需要選擇不僅沒有取消的預訂(它是在這個例子中只有ID 3)。 我可以很容易地選擇取消與簡單的WHERE change_type = cancel條件,但我很努力與NOT取消,因爲簡單的WHERE不起作用。

+0

指不等於文檔:http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_not-equal – Ric

+0

這些意見不正確的,因爲1和2有類型!=取消。 – Barmar

+0

如果我使用不等於'WHERE change_type!='取消'它打印所有保留,這是錯誤的,因爲只有保留與ID 3沒有取消 – Madr

回答

10
SELECT * 
FROM reservation 
WHERE id NOT IN (select reservation_id 
       FROM reservation_log 
       WHERE change_type = 'cancel') 

OR:

SELECT r.* 
FROM reservation r 
LEFT JOIN reservation_log l ON r.id = l.reservation_id AND l.change_type = 'cancel' 
WHERE l.id IS NULL 

第一個版本是更直觀,但我認爲第二個版本通常會得到更好的性能(假設你有在連接使用的列索引)。

第二個版本的工作原理是因爲LEFT JOIN爲第一個表中的所有行返回一行。當ON條件成功時,這些行將包含第二個表中的列,就像INNER JOIN一樣。條件失敗時,返回的行將爲第二個表中的所有列包含NULL。然後,WHERE l.id IS NULL測試會匹配那些行,以便查找表中沒有匹配的所有行。

+0

在這裏你去 - 我正在研究它... http:// sqlfiddle.com/#!2/aa49e/4 –

+0

謝謝Barmar,按我的需要工作。 – Madr

+0

@Barmar好吧,因爲你似乎希望我在這個問題上尋求幫助,而不是我自己的......如何在從子查詢調用多個列時這樣做,同時牢記內部聯接需要一個匹配列,放棄不匹配的結果,這在我的情況下不起作用,因爲我需要兩個包含用戶名的列。 – Bruce

3

爲了完整性(我真的相信它更合適),我鼓勵你使用一個簡單的NOT EXISTS

SELECT * FROM reservation R 
WHERE NOT EXISTS (
    SELECT 1 FROM reservation_log 
    WHERE reservation_id = R.id 
    AND change_type = 'cancel' 
); 
相關問題