Я провел некоторое время, пытаясь выяснить, почему этот запрос не вытягивает результаты, которые я ожидал:
SELECT * FROM NGS WHERE ESPSSN NOT IN (SELECT SSN FROM CENSUS)
наконец я пытался писать запрос иначе, и это закончило тем, что получило ожидаемые результаты:
SELECT * FROM NGS n WHERE NOT EXISTS (SELECT * FROM CENSUS WHERE SSN = n.ESPSSN)
Первый запрос кажется более соответствующим и "корректным". Я использую "в" и "не во" все время для подобных выборов и никогда не имел проблемы, о которой я знаю.
Если вы выпишите синтаксический сахар, x не в (1,2,3)
станет:
x <> 1 AND x <> 2 AND x <> 3
Итак, если Столбец ssn
содержит нулевое значение, первый запрос эквивалентен:
WHERE ESPSSN <> NULL AND ESPSSN <> ...
Результат сравнения с NULL неизвестен, поэтому запрос ничего не вернет.
Как сказал Андомар, остерегайтесь значений NULL при использовании NOT IN
Также обратите внимание, что запрос с использованием NOT IN
предикат всегда будет выполнять полное сканирование вложенных таблиц, тогда как запрос, использующий NOT EXISTS
, может использовать индекс внутри подзапроса и в результате будет выполняться намного быстрее.