有人能解释一下SQL中的以下行为吗?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
有人能解释一下SQL中的以下行为吗?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
当前回答
NULL没有值,因此不能使用标量值操作符进行比较。
换句话说,没有值可以等于(或不等于)NULL,因为NULL没有值。
因此,SQL有特殊的IS NULL和IS NOT NULL谓词来处理NULL。
其他回答
在SQL中,任何用NULL计算的结果都是UNKNOWN
这就是为什么SELECT * FROM MyTable WHERE MyColumn != NULL或SELECT * FROM MyTable WHERE MyColumn <> NULL给出0结果的原因。
为了检查NULL值,提供了isNull函数。
此外,您可以像在第三个查询中使用的那样使用IS操作符。
我想建议我做的这段代码,如果有一个值的变化, I是新的值,d是旧的值(尽管顺序无关紧要)。就此而言,从值到null的变化是变化,反之亦然,但从null到null不是(当然,从值到另一个值是变化,但从值到相同的值不是)。
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
@i sql_variant,
@d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE @in bit = 0, @dn bit = 0
if @i is null set @in = 1
if @d is null set @dn = 1
if @in <> @dn
return 0
if @in = 1 and @dn = 1
return 1
if @in = 0 and @dn = 0 and @i = @d
return 1
return 0
END
要使用此函数,可以
declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp
---- where equal ----
select *,'equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
结果如下:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
使用sql_variant可以兼容各种类型
NULL没有值,因此不能使用标量值操作符进行比较。
换句话说,没有值可以等于(或不等于)NULL,因为NULL没有值。
因此,SQL有特殊的IS NULL和IS NOT NULL谓词来处理NULL。
NULL的唯一测试是is NULL或is NOT NULL。检验是否相等是毫无意义的,因为根据定义,人们不知道值是多少。
下面是维基百科上的一篇文章:
https://en.wikipedia.org/wiki/Null_ (SQL)
<>为Standard SQL-92;=是它的等价物。两者都计算值,NULL不是——NULL是一个占位符,表示没有值。
这就是为什么在这种情况下只能使用is NULL/ is NOT NULL作为谓词的原因。
这种行为不是SQL Server特有的。所有符合标准的SQL方言都以相同的方式工作。
注意:如果你的值不是空,你使用is not null进行比较,而如果你的值不是空,你使用<> 'YOUR_VALUE'进行比较。我不能说我的值是否等于NULL,但我可以说我的值是否为NULL或not NULL。如果我的值不是NULL,我可以比较。