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ż
NULLobsł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 INjest 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