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
NULLHandhabung macht es komplexer. -
Korrektheit
Wenn einer der resultierenden Werte im Unterabfrageausdruck
NULList , ist das Ergebnis von ⒾNULL, während die übliche LogikTRUEerwarten würde - und Ⓔ gebenTRUEzurück . Das Handbuch:Wenn alle Ergebnisse pro Zeile entweder ungleich oder null sind, mit mindestens einer Null, dann ist das Ergebnis
NOT INist 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