2008-12-04 2 views
2

Я использую MS SQL 2005.T-SQL вопрос сравнения VARCHAR

Почему это дает мне правильные результаты (возвращает 169 строк) ...

select 
    * 
from 
    [import_Data] 
where 
    [import_Data].name not in 
    (
    select 
     [import_Data].name 
    from 
     [import_Data] 
     inner join [resource] on [import_Data].name = [resource].name 
    where 
     [import_Data].ProviderTypeID = 4 
     and [resource].IsDeleted = 0 
) 
    and [import_Data].ProviderTypeID = 4 

Но это не (возвращает 0 строк) ...

select 
    * 
from 
    [import_Data] 
where 
    [import_Data].name not in 
    (
    select 
     [resource].name 
    from 
     [resource] 
    where 
     IsDeleted = 0 
) 
    and [import_Data].ProviderTypeID = 4 

Единственное различие между name колонн, что [resource].name является varchar(500) и [import_Data].name является varchar(300).

ответ

6

Я думаю, что есть нулевой resource.name в таблице ресурсов, которая бросает все сравнения прочь. Почему нули являются причиной проблемы? В соответствии с «Руководством Гуру к TSQL», и я перефразирую ». В инструкциях ANSI указано, что выражение, которое сравнивает значение для равенства с NULL, всегда возвращает NULL». Таким образом, любой нуль в списке отбрасывает все это.

В вашем первом запросе ваше внутреннее соединение исключает эти нули.

Так у вас есть три варианта

  • Не использовать NOT IN, используйте НЕ СУЩЕСТВУЕТ
  • Используйте ISNULL на resource.name для устранения аннулирует
  • Изменить нулевое поведение обработки, установив ANSI_NULLS OFF ,

Пример не существует с помощью связанного подзапроса (предупреждение aircode)

SELECT * 
FROM [import_Data] 
WHERE NOT EXISTS(
     select [resource].name from [resource] where IsDeleted = 0 AND [resource].name = [import_Data].name 
    ) 
    AND [import_Data].ProviderTypeID = 4 
+0

Ответ @ Станислав Бирон имеет недостающую часть. Только «NOT IN» терпит неудачу в NULL в списке. «IN» отлично работает с NULL в списке. +1 все еще. – Tomalak

2

У вас, вероятно, есть null в колонке name таблицы [resource]. Поведение = и not in различно при использовании нулей.

Try:

select * from [resource] where name is null and IsDeleted = 0 

сузить ее.

Или исправить:

select * from [import_Data] 
where 
    [import_Data].name not in (
    select name from [resource] where IsDeleted = 0 and name is not null 
    ) 
    and [import_Data].ProviderTypeID = 4 

Также см NOT IN clause and NULL values

4

Я предполагаю, что вы сталкиваетесь с разницей в том, как IN оператора и работа = оператора внутри.

Как об этом:

select 
    * 
from 
    [import_Data] 
where 
    not exists 
    (
    select 1 
    from [resource] 
    where name = [import_Data].Name and IsDeleted = 0 
) 
    and [import_Data].ProviderTypeID = 4 
+0

Это определенно проблема с одно из значений для [resource] .name в моей базе данных - null. Как только я исправил это, он исправил проблему. –

+0

Да, теперь это ясно. НЕ СУЩЕСТВУЮЩИЙ коррелированный подзапрос еще более рекомендуется для моего POV, я почти никогда не участвую в IN с подзапросами. – Tomalak

2

На самом деле проблема заключается в том, что она выглядит как есть NULL значения в вашем [ресурс] .name столбец.

Предложение «НЕ IN» t-sql не будет работать, если в предоставленном списке значений есть значения NULL.

Это происходит потому, что ваш где будет решить, как:

[import_Data].name <> 'Resource1' and [import_Data].name <> 'Resource2' 
and [import_Data].name <> null 

когда двигатель запрос разлагает [import_Data] .name <> NULL, возвращает неизвестное значение и выражение всегда имеет значение ложь. Следовательно, вы никогда не получите ни одной строки.

Например, вы всегда будете получать 0 строк, если вы выполняете

select * from [import_Data] where [import_Data].name <> null 

Таким образом, учитывая это, следующий запрос вероятно, будет работать в вашем случае:

select * from [import_Data] 
where [import_Data].name not in (
    select [resource].name from [resource] where IsDeleted = 0 
    and [resource].name is not null 
) and [import_Data].ProviderTypeID = 4 
Смежные вопросы