У меня есть две таблицы с привязкой первичного ключа в базе данных, и я хочу найти непересекающийся набор между ними. Например,
Table1
имеет columns (ID, Name
) и образцы данных:(1 ,John), (2, Peter), (3, Mary)
Table2
имеет columns (ID, Address
) и образцы данных:(1, address2), (2, address2)
Итак, как мне создать SQL-запрос, чтобы я мог получить строку с идентификатором table1
, которого нет table2
. В этом случае (3, Mary)
следует вернуть?
Ps. ID - это первичный ключ для этих двух таблиц.
Заранее спасибо.
sql
database
postgresql
johnklee
источник
источник
Ответы:
Попробуй это
источник
использование
LEFT JOIN
источник
Есть в основном 3 подхода к тому , что:
not exists
,not in
иleft join / is null
.LEFT JOIN с IS NULL
НЕ В
НЕ СУЩЕСТВУЕТ
Какой лучше? Ответ на этот вопрос было бы лучше разделить на основных конкретных поставщиков СУБД. Вообще говоря, следует избегать использования,
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/
источник
Быстрая альтернатива
Я провел несколько тестов (на postgres 9.5), используя две таблицы по ~ 2 млн строк в каждой. Этот запрос ниже работал как минимум в 5 * лучше, чем другие предложенные запросы:
источник
Принимая во внимание моменты, сделанные в комментарии / ссылке @John Woo выше, я обычно поступаю следующим образом:
источник
источник