Проблема с «НЕ В» в простом запросе SQL - PullRequest
4 голосов
/ 22 сентября 2011

Мне нужно найти все идентификаторы из OldTable, которых нет в NewTable
Почему этот запрос не найдет идентификатор?

SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)  

Они сами возвращают это

--Returns the id 18571
SELECT old_id FROM OldTable WHERE old_id = 18571

 --Returns nothing  
SELECT id FROM NewTable WHERE id = 18571 

Я что-то упускаю здесь очевидное?

Оба столбца имеют тип int и первичные ключи.

РЕШЕНО

В столбце id были нулевые значения, я просто не знал = /

Эти работы:

SELECT old_id FROM OldTable EXCEPT SELECT id FROM NewTable  

SELECT * FROM old_table ot WHERE NOT EXISTS (
SELECT * FROM new_table nt WHERE nt.id = ot.old_id)  

Это не работает:

SELECT old_id FROM OldTable LEFT JOIN NewTable ON old_id = id WHERE id IS NULL  

SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)

Ответы [ 5 ]

2 голосов
/ 22 сентября 2011

Разницу можно объяснить наличием нулей.

Рассмотрим эти два упрощенных запроса, отметив, что предикатом для обоих является NULL = 1, который оценивается как UNKNOWN, который обрабатывается по-разному NOT EXISTS и NOT IN соответственно:

SELECT *
  FROM OldTable
 WHERE NULL NOT IN (SELECT 1 FROM OldTable);

 SELECT *
  FROM OldTable
 WHERE NOT EXISTS (SELECT * FROM OldTable WHERE NULL = 1);

Первая строка не возвращает строк, поскольку NOT IN (subquery) оценивается как FALSE.

Первая возвращает все строки, поскольку NOT EXISTS (subquery) оценивается как ИСТИНА.

Вывод: избегайте нулей.

2 голосов
/ 22 сентября 2011
SELECT * FROM old_table ot
WHERE NOT EXISTS (
   SELECT * FROM new_table nt
   WHERE nt.new_key = ot.old_key
   );
1 голос
/ 22 сентября 2011

Я не знаю, почему ваш запрос не дает желаемого результата, но я знаю, что использование NOT IN не очень эффективно. Вам лучше использовать соединения:

SELECT old_id 
FROM OldTable 
LEFT JOIN NewTable
    ON old_id = id
WHERE id IS NULL
0 голосов
/ 22 сентября 2011
select oldtable.id as orginal, newtable.id as new 
from oldtable 
left outer join newtable 
on oldtable.id =newtable.id 
where new is null

AFAIK (а я не эксперт - проверь мою репутацию ;-) левое внешнее объединение - хорошая техника для этого .. может выполнить не в и не требует дополнительного выбора

@ oneday, когда любезно указывает, что это не всегда так, например. в SQL Server EXISTS () может быть более эффективным.

0 голосов
/ 22 сентября 2011
SELECT old_id FROM OLDTable WHERE id not in (SELECT id from NewTable);

Вы используете old_id в условии where в первом запросе и используете id во втором запросе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...