Verwenden Sie ein EXISTS
Ausdruck:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Der Unterschied
... zwischen NOT EXISTS()
(Ⓔ) und NOT IN()
(Ⓘ) ist zweifach:
-
Leistung
Ⓔ ist generell schneller. Es stoppt die Verarbeitung der Unterabfrage, sobald die erste Übereinstimmung gefunden wird. Das Handbuch:
Die Unterabfrage wird im Allgemeinen nur lange genug ausgeführt, um festzustellen, ob mindestens eine Zeile zurückgegeben wird, nicht bis zum Ende.
Ⓘ kann auch vom Abfrageplaner optimiert werden, jedoch in geringerem Maße, da
NULL
Handhabung macht es komplexer. -
Korrektheit
Wenn einer der resultierenden Werte im Unterabfrageausdruck
NULL
ist , ist das Ergebnis von ⒾNULL
, während die übliche LogikTRUE
erwarten würde - und Ⓔ gebenTRUE
zurück . Das Handbuch:Wenn alle Ergebnisse pro Zeile entweder ungleich oder null sind, mit mindestens einer Null, dann ist das Ergebnis
NOT IN
ist null.
Im Wesentlichen existiert (NOT) EXISTS
ist in den meisten Fällen die bessere Wahl.
Beispiel
Ihre Abfrage kann wie folgt aussehen:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
nicht Nehmen Sie an votes
teil in der Basisabfrage. Das würde den Aufwand zunichte machen.
Außer NOT EXISTS
und NOT IN
es gibt zusätzliche Syntaxoptionen mit LEFT JOIN / IS NULL
und EXCEPT
. Siehe:
- Wählen Sie Zeilen aus, die in keiner anderen Tabelle vorhanden sind