Sql server T-sqlvarchar比较问题

Sql server T-sqlvarchar比较问题,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,我正在使用MS Sql 2005 为什么这会给我正确的结果(返回169行) 但这不会(返回0行) name列之间唯一的区别是[resource].name是varchar(500)和[import\u Data]。name是varchar(300) 您可能在[resource]表的name列的某处有一个null。当涉及空值时,=和不在中的行为是不同的 尝试: 缩小范围 或修复: select * from [import_Data] where [import_Data].name not

我正在使用MS Sql 2005

为什么这会给我正确的结果(返回169行)

但这不会(返回0行)


name
列之间唯一的区别是
[resource].name
varchar(500)
[import\u Data]。name
varchar(300)

您可能在
[resource]
表的
name
列的某处有一个
null
。当涉及空值时,
=
不在
中的行为是不同的

尝试:

缩小范围

或修复:

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

另请参见

我的猜测是中的
操作符和
=
操作符内部工作的方式不同

这个怎么样:

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

我猜您的资源表中有一个空的resource.name,它会使所有比较都失效。 为什么空值会导致问题?根据“Guru's Guid to TSQL”,我正在解释“ANSI指南规定,将相等值与NULL值进行比较的表达式总是返回NULL”。因此,列表中的任何NULL都会导致整个问题

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

所以你有三个选择

  • 不使用不在,使用不存在
  • 在resource.name上使用ISNULL可消除空值
  • 通过禁用ANSI_null来更改null处理行为
使用相关子查询(警告代码)的示例不存在


事实上,问题在于[resource].name列中似乎有空值

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

这是因为您的where将解析为:

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

@Stanislas Biron的回答缺少了部分。只有“不在”在列表中为空时失败。“IN”在列表中为NULL时可以正常工作+仍然为1。我的数据库中[resource].name的某个值为null肯定是个问题。我一纠正,问题就解决了。是的,我现在也清楚了。从我的观点来看,不存在的相关子查询仍然更值得推荐,我几乎从不让我们不使用子查询。
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
select 
  * 
from 
  [import_Data] 
where 
  not exists 
  (
    select 1 
    from   [resource] 
    where  name = [import_Data].Name and IsDeleted = 0
  ) 
  and [import_Data].ProviderTypeID = 4
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
[import_Data].name <> 'Resource1' and [import_Data].name <> 'Resource2' 
and [import_Data].name <> null
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