Есть в основном 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/