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
NULLhantering 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