Użyj EXISTS
wyrażenie:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Różnica
... między NOT EXISTS()
(Ⓔ) i NOT IN()
(Ⓘ) jest dwojaki:
-
Wydajność
Ⓔ jest generalnie szybszy. Przerywa przetwarzanie podzapytania, gdy tylko zostanie znalezione pierwsze dopasowanie. Instrukcja:
Podzapytanie będzie generalnie wykonywane tylko na tyle długo, aby określić, czy zwrócony jest przynajmniej jeden wiersz, a nie do końca.
Ⓘ może być również zoptymalizowany przez planer zapytań, ale w mniejszym stopniu, ponieważ
NULL
obsługa czyni to bardziej złożonym. -
Prawidłowość
Jeśli jedna z wartości wynikowych w wyrażeniu podzapytania to
NULL
, wynikiem Ⓘ jestNULL
, podczas gdy zwykła logika oczekiwałabyTRUE
- i Ⓔ zwróciTRUE
. Instrukcja:Jeśli wszystkie wyniki dla każdego wiersza są nierówne lub null, z co najmniej jednym null, wynik
NOT IN
jest zerowe.
Zasadniczo (NOT) EXISTS
jest lepszym wyborem w większości przypadków.
Przykład
Twoje zapytanie może wyglądać tak:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
Nie dołącz do votes
w zapytaniu podstawowym. To unieważniłoby wysiłek.
Poza tym NOT EXISTS
i NOT IN
istnieją dodatkowe opcje składni z LEFT JOIN / IS NULL
i EXCEPT
. Zobacz:
- Wybierz wiersze, których nie ma w innej tabeli