2011-12-11 14 views
55

sto cercando di eseguire questa query:PostgreSQL 'NON IN' e subquery

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

ma ottengo alcun risultato. L'ho provato e so che c'è qualcosa di sbagliato nella sintassi. In MySQL tale query funziona perfettamente. Ho aggiunto una riga per essere sicuro che ci sia uno mac che non esiste nella tabella consols, ma ancora non sta dando alcun risultato.

+4

La colonna 'consols.mac'' NULL' o 'NOT NULL'? –

risposta

96

quando non si utilizza IN è necessario assicurarsi che nessuno dei valori sono 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

Nota: la clausola 'WHERE mac NON È NULL' nella subquery non è necessaria, poiché' In (...) 'rimuove sempre NULL (e duplicati). Perché un set non può contenere NULL – wildplasser

+3

@wildplasser, non lo so. Non funzionava per me, fino a quando non ho aggiunto "NON È NULL". Il 'nidificato' annidato restituiva alcuni 'NULLS', e questo stava facendo scattare il' IN (SELECT ...) '. – robins35

+1

Apprezzerei molto una spiegazione sul perché il comando 'IS NOT NULL' fa sì che funzioni. – mbarkhau

25

Quando si usa NOT IN, si dovrebbe anche considerare NON ESISTE, che gestisce i casi nulli in silenzio.

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

Si noti inoltre un'enorme perdita di prestazioni quando si utilizza 'NOT EXISTS' vs' ... NOT IN' – IcanDivideBy0

+1

@ IcanDivideBy0 Nella maggior parte dei casi i casi generano lo stesso piano di query. L'hai provato? – wildplasser

6

Si potrebbe anche usare un LEFT JOIN e IS NULL condizione:

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

un indice sulle colonne "mac" potrebbe migliorare le prestazioni.