考虑以下Transact sql。
DECLARE @table TABLE(val VARCHAR(255) NULL)
INSERT INTO @table (val) VALUES('a')
INSERT INTO @table (val) VALUES('b')
INSERT INTO @table (val) VALUES('c')
INSERT INTO @table (val) VALUES('d')
INSERT INTO @table (val) VALUES(NULL)
select val
from @table
where val not in ('a')
我希望这会回来
b, c, d, NULL
但它会返回
b, c, d
为什么会这样?是否未评估NULL?在某个'a'中是否为NULL?
答案 0 :(得分:3)
获取空行尝试:
select val
from @table
where val not in ('a') OR val IS NULL
试试这些:
select 1 where null in (null)
select 1 where null in (1)
select 1 where 1 in (null)
全部返回零行
null = null始终为false 且 null = anythng始终为false ,在测试NULL行时,WHERE子句在('a')中为WHERE NULL,因此它总是错误的。
答案 1 :(得分:3)
答案
默认情况下,NULL表示SQL,表示“未知”。因此,与“未知”的任何比较都是“未知”。
例如,如果一个陌生人站在鲍勃旁边,你想问一个问题,“陌生人的名字和鲍勃的名字一样吗?”。答案是未知的。
因为您要求“返回任何值不是'A'的记录”。当它到达那个NULL列时,SQL仍然说,“我不知道”。由于表达式的计算结果为true,因此不会返回该记录。
解决方案
将NULL与常量进行比较的任何表达式始终为NULL,因此请使用特殊IS NULL
和IS NOT NULL
来测试NULL值。
这会让您b
,c
,d
和NULL
:
SELECT val
FROM @table
WHERE val NOT IN ('a') OR val IS NULL
解决方法
您可以更改NULL的默认行为:
SET ANSI_NULLS OFF
答案 2 :(得分:2)
Null不能直接与任何东西进行比较。
试
select val
from @table
where coalesce(val, '') not in ('a')
答案 3 :(得分:2)
试试这个,你会得到一个不同的答案:
set ansi_nulls off;
DECLARE @table TABLE(val VARCHAR(255) NULL)
INSERT INTO @table (val) VALUES('a')
INSERT INTO @table (val) VALUES('b')
INSERT INTO @table (val) VALUES('c')
INSERT INTO @table (val) VALUES('d')
INSERT INTO @table (val) VALUES(NULL)
select val
from @table
where val not in ('a')
你有ansi_nulls,因此它会相应地处理空值。
答案 4 :(得分:2)
以这种方式不能与NULL相等。
考虑一下
select case when 'a' = NULL then 1 else 0 end
select case when 'a' <> NULL then 1 else 0 end
上面你会得到
result
------
0
0
对于您的查询,请尝试
where isnull(val,'') not in ('a')