Brug en EXISTS
udtryk:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Forskellen
... mellem NOT EXISTS()
(Ⓔ) og NOT IN()
(Ⓘ) er todelt:
-
Ydeevne
Ⓔ er generelt hurtigere. Det stopper med at behandle underforespørgslen, så snart det første match er fundet. Manualen:
Underforespørgslen vil generelt kun blive udført længe nok til at afgøre, om mindst én række returneres, ikke hele vejen til færdiggørelse.
Ⓘ kan også optimeres af forespørgselsplanlæggeren, men i mindre grad siden
NULL
håndtering gør det mere komplekst. -
Korrekthed
Hvis en af de resulterende værdier i underforespørgselsudtrykket er
NULL
, resultatet af Ⓘ erNULL
, mens almindelig logik ville forventeTRUE
- og Ⓔ vil returnereTRUE
. Manualen:Hvis alle resultater pr. række er enten ulige eller null, med mindst én nul, så resultatet af
NOT IN
er nul.
Grundlæggende FINDER (NOT) EXISTS
er det bedre valg i de fleste tilfælde.
Eksempel
Din forespørgsel kan se sådan ud:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
Gør ikke deltage i votes
i basisforespørgslen. Det ville annullere indsatsen.
Udover NOT EXISTS
og NOT IN
der er yderligere syntaksmuligheder med LEFT JOIN / IS NULL
og EXCEPT
. Se:
- Vælg rækker, der ikke findes i en anden tabel