Вопрос:
Я пытаюсь выполнить следующий запрос, но он не получает никаких данных, хотя он должен получить одну строку:
select * from [DB1.table1] where col1 not in (select col2 from DB2.table2)
col1, col2 имеют тип varchar
почему это не работает?
Лучший ответ:
“Не работает” – не совсем хорошее описание вашей проблемы, но почти во всех случаях это вызвано возвращаемыми значениями NULL подвыбора.
Вы, вероятно, захотите этого:
select * from [DB1.table1] where col1 not in (select col2 from DB2.table2 where col2 is not null);
Сравнение с NULL всегда дает “undefined”, и, таким образом, если хотя бы одна строка из подвыборки содержит NULL в столбце col2 все выражение “undefined”. Поскольку undefined не “true”, весь запрос ничего не возвращает.
Ответ №1
Если у вас есть NULL в col2 в table2, вы получите поведение, вы можете описать:
create table table2 ( col2 varchar(10) null ) insert into table2 (col2) values (‘abc’),(null) create table table1 ( col1 varchar(10) null ) insert into table1 (col1) values (‘abc’),(‘def’) select * from table1 where col1 not in (select col2 from table2)
Не создает строк. Это происходит потому, что результат NOT IN становится UNKNOWN когда происходит сравнение NULL.
Вы можете исправить это с помощью:
select * from table1 where col1 not in (select col2 from table2 where col2 is not null)
Если это правильная логика для вашего ситутации.
Ответ №2
Поскольку другие уже указали на причину, которая вызывает эту проблему, вы можете добиться тех же результатов, используя LEFT JOIN и это безопасно, чем предикат IN с NULL vlaues:
select t1.* from [DB1.table1] AS T1 LEFT JOIN DB2.table2 AS t2 ON t1.col1 = t2.col2 where t1.col2 IS NULL;