2011-12-11 25 views
55

我試圖執行這個查詢:PostgreSQL的 'NOT IN' 和子查詢

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11 
AND mac NOT IN (select consols.mac from consols) 

但我沒有得到任何結果。我測試了它,並且我知道語法有問題。在MySQL中,這樣的查詢完美工作。我已經添加了一行以確保mac不存在於consols表中,但仍然沒有給出任何結果。

+4

'consols.mac'列是NULL還是NOT NULL? –

回答

96

當使用NOT IN,你應該確保沒有一個數值是NULL:

SELECT mac, creation_date 
FROM logs 
WHERE logs_type_id=11 
AND mac NOT IN (
    SELECT mac 
    FROM consols 
    WHERE mac IS NOT NULL -- add this 
) 
+2

注意:子查詢中的WHERE mac IS NOT NULL子句不需要,因爲In(...)總是刪除NULL(和重複)。因爲一個集合不能包含空值 – wildplasser

+3

@wildplasser我不知道這一點。這不是爲我工作,直到我添加了「IS NOT NULL」。嵌套的'SELECT'返回一些'NULLS',並且正在跳出'IN(SELECT ...)'。 – robins35

+1

我非常感謝爲什麼'IS NOT NULL'導致這個工作的解釋。 – mbarkhau

25

當使用NOT IN,你也應該考慮不存在,這默默處理空的情況。

SELECT mac, creation_date 
FROM logs lo 
WHERE logs_type_id=11 
AND NOT EXISTS (
    SELECT * 
    FROM consols nx 
    WHERE nx.mac = lo.mac 
); 
+1

另請注意,使用「NOT EXISTS」和「... NOT IN」時性能損失巨大 – IcanDivideBy0

+1

@ IcanDivideBy0在大多數情況下他們會生成相同的查詢計劃。你測試過了嗎? – wildplasser

6

您也可以使用LEFT JOIN和IS NULL條件:

SELECT 
    mac, 
    creation_date 
FROM 
    logs 
    LEFT JOIN consols ON logs.mac = consols.mac 
WHERE 
    logs_type_id=11 
AND 
    consols.mac IS NULL; 

在 「陸委會」 列的索引可以提高性能。