Använd en EXISTS
uttryck:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Skillnaden
... mellan NOT EXISTS()
(Ⓔ) och NOT IN()
(Ⓘ) är tvåfaldigt:
-
Prestanda
Ⓔ är i allmänhet snabbare. Den slutar bearbeta underfrågan så snart den första matchningen hittas. Manualen:
Underfrågan kommer i allmänhet bara att köras tillräckligt länge för att avgöra om minst en rad returneras, inte hela vägen till slutförandet.
Ⓘ kan också optimeras av frågeplaneraren, men i mindre utsträckning eftersom
NULL
hantering gör det mer komplext. -
Riktigt
Om ett av de resulterande värdena i underfrågeuttrycket är
NULL
, resultatet av Ⓘ ärNULL
, medan vanlig logik förväntar sigTRUE
- och Ⓔ returnerarTRUE
. Manualen:Om alla resultat per rad är antingen ojämlika eller null, med minst en null, då resultatet av
NOT IN
är null.
I huvudsak (NOT) EXISTS
är det bättre valet i de flesta fall.
Exempel
Din fråga kan se ut så här:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
Gör inte gå med för att votes
i basfrågan. Det skulle göra ansträngningen ogiltig.
Förutom NOT EXISTS
och NOT IN
det finns ytterligare syntaxalternativ med LEFT JOIN / IS NULL
och EXCEPT
. Se:
- Välj rader som inte finns i andra tabeller