T-SQL varchar比较问题

时间:2008-12-04 18:30:11

标签: sql-server sql-server-2005 tsql

我正在使用MS Sql 2005。

为什么这会给我正确的结果(返回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].namevarchar(500)[import_Data].namevarchar(300)

4 个答案:

答案 0 :(得分:6)

我的猜测是资源表中有一个null resource.name,它会抛弃所有的比较。 为什么空值会导致问题?根据“Guru对TSQL的指导”,我正在解释“ANSI指南声明将相等值与NULL进行比较的表达式总是返回NULL。”因此列表中的任何null都会抛出整个内容。

在第一个查询中,您的内部联接会排除这些空值。

所以你有三个选择

  • 请勿使用NOT IN,请使用NOT EXISTS
  • 在resource.name上使用ISNULL来消除空值
  • 通过将ANSI_NULLS设置为OFF来更改空值处理行为。

使用相关子查询(警告空中代码)不存在的示例

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

答案 1 :(得分: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

答案 2 :(得分:2)

null表的某个name列中可能有一个[resource]。当涉及空值时,=not in的行为会有所不同。

尝试:

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

答案 3 :(得分:2)

实际上问题是,[resource] .name列中看起来有NULL值。

当提供的值列表中有NULL值时,“NOT IN”t-sql子句将不起作用。

这是因为您将在哪里解决:

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

当查询引擎解析[import_Data] .name&lt;&gt; null,它返回一个UNKNOWN值,表达式总是计算为false。因此,你永远不会得到任何一行。

例如,如果执行

,您将始终获得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