Gebruik een EXISTS
uitdrukking:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Het verschil
... tussen NOT EXISTS()
(Ⓔ) en NOT IN()
(Ⓘ) is tweeledig:
-
Prestaties
Ⓔ is over het algemeen sneller. Het stopt met het verwerken van de subquery zodra de eerste overeenkomst is gevonden. De handleiding:
De subquery wordt over het algemeen alleen lang genoeg uitgevoerd om te bepalen of ten minste één rij wordt geretourneerd, niet helemaal tot voltooiing.
Ⓘ kan ook worden geoptimaliseerd door de queryplanner, maar in mindere mate sinds
NULL
behandeling maakt het complexer. -
Juistheid
Als een van de resulterende waarden in de subquery-expressie
NULL
. is , het resultaat van Ⓘ isNULL
, terwijl de algemene logica zou verwachten datTRUE
- en Ⓔ retourneertTRUE
. De handleiding:Als alle resultaten per rij ongelijk of null zijn, met ten minste één null, dan is het resultaat van
NOT IN
is nul.
In wezen, (NOT) EXISTS
is in de meeste gevallen de betere keuze.
Voorbeeld
Uw vraag kan er als volgt uitzien:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
Doe niet doe mee met votes
in de basisquery. Dat zou de moeite teniet doen.
Naast NOT EXISTS
en NOT IN
er zijn extra syntaxisopties met LEFT JOIN / IS NULL
en EXCEPT
. Zie:
- Selecteer rijen die niet aanwezig zijn in een andere tabel