Есть в основном 3 подхода к тому , что: not exists, not inи left join / is null.
LEFT JOIN с IS NULL
SELECT l.*
FROM t_left l
LEFT JOIN
t_right r
ON r.value = l.value
WHERE r.value IS NULL
НЕ В
SELECT l.*
FROM t_left l
WHERE l.value NOT IN
(
SELECT value
FROM t_right r
)
НЕ СУЩЕСТВУЕТ
SELECT l.*
FROM t_left l
WHERE NOT EXISTS
(
SELECT NULL
FROM t_right r
WHERE r.value = l.value
)
Какой лучше? Ответ на этот вопрос было бы лучше разделить на основных конкретных поставщиков СУБД. Вообще говоря, следует избегать использования, select ... where ... in (select...)когда величина количества записей в подзапросе неизвестна. Некоторые поставщики могут ограничивать размер. Oracle, например, имеет ограничение в 1000 . Лучше всего попробовать все три и показать план выполнения.
Конкретно форма PostgreSQL, план выполнения NOT EXISTSи LEFT JOIN / IS NULLтакой же. Я лично предпочитаю этот NOT EXISTSвариант, потому что он лучше показывает намерение. В конце концов семантический, что вы хотите , чтобы найти записи в том , что его рк не существует в B .
Старый, но все же золотой, но характерный для PostgreSQL: https://explainextended.com/2009/09/16/not-in-vs-not-exists-vs-left-join-is-null-postgresql/