提问人:Maxim Gershkovich 提问时间:4/14/2011 最后编辑:BenMaxim Gershkovich 更新时间:5/19/2022 访问量:569698
不等于 NULL 上的 <> != 运算符
Not equal <> != operator on NULL
问:
有人可以解释一下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-92; 是它的等价物。两者都计算值,但值不是 -- 是一个占位符,表示没有值。!=
NULL
NULL
这就是为什么在这种情况下,您只能使用 / 作为谓词。IS NULL
IS NOT NULL
此行为并非特定于 SQL Server。所有符合标准的 SQL 方言都以相同的方式工作。
注意:要比较您的值是否为空,请使用 ,而要与非空值进行比较,请使用 .我不能说我的值是否等于 NULL,但我可以说我的值是 NULL 还是 NOT NULL。我可以比较我的值是否不是 NULL。IS NOT NULL
<> 'YOUR_VALUE'
评论
<>
!=
!=
!=
<>
WHERE MyColumn != NULL
WHERE MyColumn = NULL
MyColumn
!=
WHERE MyColumn != 'somevalue'
NULL 的唯一测试是 IS NULL 或 IS NOT NULL。测试相等性是荒谬的,因为根据定义,人们不知道值是什么。
这是一篇维基百科文章:
https://en.wikipedia.org/wiki/Null_(SQL)
NULL 没有值,因此不能使用标量值运算符进行比较。
换句话说,任何值都不能等于(或不等于)NULL,因为 NULL 没有值。
因此,SQL 具有特殊的 IS NULL 和 IS NOT NULL 谓词来处理 NULL。
评论
'a' != null
true
1
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
NULL 不能使用比较运算符与任何值进行比较。NULL = NULL 为 false。Null 不是值。IS 运算符专门设计用于处理 NULL 比较。
评论
null = null
1=0
null != null
在 SQL 中,您评估/计算的任何结果都为 UNKNOWNNULL
这就是为什么或给你 0 个结果。SELECT * FROM MyTable WHERE MyColumn != NULL
SELECT * FROM MyTable WHERE MyColumn <> NULL
为了提供对值的检查,提供了 isNull 函数。NULL
此外,您可以像在第三个查询中使用的那样使用运算符。IS
评论
请注意,此行为是默认 (ANSI) 行为。
如果您:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
你会得到不同的结果。
SET ANSI_NULLS OFF
显然将来会消失......
评论
create unique index UK_MyTable on MyTable (Column) where Column is not null
SET ANSI_NULLS
为 OFF 时,等于 (=) 和不等于 (<>) 比较运算符不遵循 ISO 标准。使用 WHERE column_name = NULL
的 SELECT 语句返回 column_name 中具有 null 值的行。使用 WHERE column_name <> NULL
的 SELECT 语句返回列中具有非 null 值的行。此外,使用 WHERE column_name <> XYZ_value
的 SELECT 语句将返回所有未XYZ_value且非 NULL 的行。恕我直言,最后这句话似乎有点奇怪,因为它从结果中排除了空值!
NULL 什么都不是......这是未知的。NULL 不等同于任何东西。这就是为什么您必须在 SQL 查询中使用魔术短语 IS NULL 而不是 = NULL 的原因
您可以参考以下内容:http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
我想建议我编写的这段代码来查找值是否有变化,是新值还是旧值(尽管顺序无关紧要)。就此而言,从 value 到 null 的更改,反之亦然,但从 null 到 null 的更改不是(当然,从值到另一个值是更改,但从值到相同不是)。i
d
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的使用使其与多种类型兼容
我们使用
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
返回 MyColumn 为 NULL 的所有行或 MyColumn 为空字符串的所有行。对于许多“最终用户”来说,NULL 与空字符串问题是一种区别,没有必要和混淆点。
评论
null
表示无值或未知值。它没有具体说明为什么没有值,这可能会导致一些歧义。
假设您运行如下查询:
SELECT *
FROM orders
WHERE delivered=ordered;
也就是说,您正在寻找 和 日期相同的行。ordered
delivered
当一列或两列为 null 时会发生什么?
因为至少有一个日期是未知的,所以你不能指望说这两个日期是相同的。当两个日期都未知时,情况也是如此:如果我们甚至不知道它们是什么,它们怎么可能相同?
因此,任何被视为值的表达式都必须失败。在这种情况下,它将不匹配。如果您尝试以下操作,情况也是如此:null
SELECT *
FROM orders
WHERE delivered<>ordered;
同样,如果我们不知道两个值是什么,我们怎么能说它们不相同。
SQL 对缺失值有一个特定的测试:
IS NULL
具体来说,它不是比较值,而是寻找缺失的值。
最后,关于运营商,据我所知,它实际上并不在任何标准中,但它得到了非常广泛的支持。添加它是为了让某些语言的程序员感到更自在。坦率地说,如果程序员难以记住他们使用的是什么语言,那么他们就有一个糟糕的开始。!=
评论
NULL
NULL
NULL
IS NULL
= NULL
WHERE columnA = columnB
WHERE columnA = NULL
NULL
variable == null
null
IS NULL
=NULL
评论