Строки таблицы A, у которых нет совпадения в таблице B — двумя способами
Таблицы a(id) и b(a_id). Верните каждую строку a, у которой нет совпадающей строки в b — анти-джойн. Приведите два независимых запроса с одинаковым результатом, использующих разные механизмы.
-- способ 1 и способ 2: строки a, которых нет в b
Напишите оба запроса.
Способ один — LEFT JOIN b ON b.a_id = a.id WHERE b.a_id IS NULL, оставляя несопоставленные левые строки. Способ два — WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.a_id = a.id). Предпочитайте NOT EXISTS: NOT IN ломается на NULL в подзапросе.
- ✗Брать INNER JOIN, который возвращает совпадения, а не их отсутствие
- ✗Считать, что NOT IN и NOT EXISTS ведут себя одинаково при наличии NULL
- ✗Фильтровать по IS NOT NULL не той стороны и переворачивать результат
- →Почему NULL в подзапросе ломает NOT IN, но не NOT EXISTS?
- →Как планировщик обычно выполняет форму LEFT JOIN / IS NULL?
Both queries return the rows of a absent from b, by two different mechanisms.
-- Way 1: outer join, keep the rows that stayed unmatched
SELECT a.*
FROM a
LEFT JOIN b ON b.a_id = a.id
WHERE b.a_id IS NULL;
-- Way 2: correlated NOT EXISTS
SELECT a.*
FROM a
WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.a_id = a.id);
Prefer NOT EXISTS over NOT IN (SELECT a_id FROM b): if any b.a_id is NULL, the NOT IN comparison becomes UNKNOWN for every outer row and the query returns nothing. NOT EXISTS is null-safe and usually plans the same as the outer-join form.