Použijte EXISTS
výraz:
WHERE NOT EXISTS (
SELECT FROM votes v -- SELECT list can be empty
WHERE v.some_id = base_table.some_id
AND v.user_id = ?
)
Rozdíl
... mezi NOT EXISTS()
(Ⓔ) a NOT IN()
(Ⓘ) je dvojí:
-
Výkon
Ⓔ je obecně rychlejší. Jakmile je nalezena první shoda, zastaví zpracování poddotazu. Manuál:
Poddotaz bude obecně proveden pouze tak dlouho, aby bylo možné určit, zda je vrácen alespoň jeden řádek, nikoli až do konce.
Ⓘ lze také optimalizovat plánovačem dotazů, ale v menší míře, protože
NULL
manipulace je složitější. -
Správnost
Pokud je jedna z výsledných hodnot ve výrazu poddotazu
NULL
, výsledek Ⓘ jeNULL
, zatímco běžná logika by očekávalaTRUE
- a Ⓔ vrátíTRUE
. Manuál:Pokud jsou všechny výsledky na řádku buď nestejné nebo null, s alespoň jednou hodnotou null, pak výsledek
NOT IN
je null.
V podstatě (NOT) EXISTS
je ve většině případů lepší volbou.
Příklad
Váš dotaz může vypadat takto:
SELECT *
FROM questions q
WHERE NOT EXISTS (
SELECT FROM votes v
WHERE v.question_id = q.id
AND v.user_id = ?
);
Ne připojit se k votes
v základním dotazu. Ztratilo by to úsilí.
Kromě NOT EXISTS
a NOT IN
existují další možnosti syntaxe s LEFT JOIN / IS NULL
a EXCEPT
. Viz:
- Vyberte řádky, které se nenacházejí v jiné tabulce