Bel*_*igh 4 null sql-server sql-server-2008-r2
我有一个与下面结构相似的表,一个字段中有一个NULL
值。当我查询表时,这条记录没有返回,它被省略了。应如何更改查询以返回此记录?
Declare @Fiesty Table
(
numberfour varchar(100)
,valid varchar(20)
)
Insert Into @Fiesty (numberfour, valid) Values
('1ACRELBS', NULL), ('4ACRELBS', 'Green'), ('17ACRELBS', 'White')
Select * FROM @Fiesty WHERE valid NOT IN ('Green', 'Blue', 'White')
Run Code Online (Sandbox Code Playgroud)
我预期的返回结果将是 numberfour = 1ACRELBS
ype*_*eᵀᴹ 19
SQL 使用三元(三值)逻辑,与 的比较NULL
很棘手,违反直觉。关于条件:
WHERE valid NOT IN ('Green', 'Blue', 'White')
Run Code Online (Sandbox Code Playgroud)
它扩展为:
WHERE valid <> 'Green' AND valid <> 'Blue' AND valid <> 'White'
Run Code Online (Sandbox Code Playgroud)
当valid
是 时NULL
,所有这 3 个子条件的计算结果都为UNKNOWN
(既不是TRUE
也不是FALSE
)。整个条件也评估UNKNOWN
为,因此行被拒绝(WHERE
仅保留条件评估为的行TRUE
)。
在比较空值时,您可以这样想。我不知道的确切值,valid
所以我不能确定它是否会有所不同'Green'
。它可能是,也可能不是。结果是UNKNOWN
。
如果目的是获取结果中的行 where valid IS NULL
,您可以使用:
SELECT * FROM @Fiesty
WHERE valid IS NULL
OR valid NOT IN ('Green', 'Blue', 'White') ;
Run Code Online (Sandbox Code Playgroud)
或EXISTS / EXCEPT
(或NOT EXISTS / INTERSECT
):
SELECT f.* FROM @Fiesty AS f
WHERE EXISTS
( SELECT f.valid
EXCEPT
SELECT v.valid
FROM
( VALUES ('Green'), ('Blue'), ('White') )
AS v (valid)
) ;
Run Code Online (Sandbox Code Playgroud)
还有一种NOT EXISTS
我认为比 更喜欢的方法NOT IN
,特别是因为有关空值的行为更直观。(还要注意与INTERSECT
版本的相似性):
SELECT f.* FROM Fiesty AS f
WHERE NOT EXISTS
( SELECT *
FROM
( VALUES ('Green'), ('Blue'), ('White') )
AS v (valid)
WHERE v.valid = f.valid
) ;
Run Code Online (Sandbox Code Playgroud)
在dbfiddle.uk测试。
归档时间: |
|
查看次数: |
781 次 |
最近记录: |