不等于<> !=运算符为NULL

时间:2011-04-14 04:15:32

标签: sql sql-server tsql 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)

11 个答案:

答案 0 :(得分:279)

<>是标准SQL-92; !=就是等价物。两者都评估值NULL不是 - NULL是一个占位符,表示没有值。

这就是为什么您只能使用IS NULL / IS NOT NULL作为此类情况的谓词。

此行为并非特定于SQL Server。所有符合标准的SQL方言都以相同的方式工作。

注意:要比较值是否为空,请使用IS NOT NULL,同时与非空值进行比较,你使用<> 'YOUR_VALUE'。我不能说我的值是否等于NULL,但我可以说我的值是NULL还是NOT NULL。如果我的值不是NULL,我可以比较。

答案 1 :(得分:81)

NULL没有值,因此无法使用标量值运算符进行比较。

换句话说,没有值可以等于(或不等于)NULL,因为NULL没有值。

因此,SQL具有特殊的IS NULL和IS NOT NULL谓词来处理NULL。

答案 2 :(得分:25)

请注意,此行为是默认(ANSI)行为。

如果你:

 SET ANSI_NULLS OFF

http://msdn.microsoft.com/en-us/library/ms188048.aspx

你会得到不同的结果。

SET ANSI_NULLS OFF显然将来会消失......

答案 3 :(得分:7)

对NULL的唯一测试是IS NULL或IS NOT NULL。对等同性进行测试是没有意义的,因为根据定义,人们不知道该值是什么。

这是一篇维基百科文章:

https://en.wikipedia.org/wiki/Null_(SQL)

答案 4 :(得分:7)

在SQL中,使用NULL评估/计算的任何内容都会导致UNKNOWN

这就是SELECT * FROM MyTable WHERE MyColumn != NULLSELECT * FROM MyTable WHERE MyColumn <> NULL为您提供0结果的原因。

为了检查NULL值,提供了isNull函数。

此外,您可以使用第三个查询中使用的IS运算符。

希望这有帮助。

答案 5 :(得分:6)

我们使用

SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';

返回MyColumn为NULL的所有行或MyColumn为空字符串的所有行。对于许多“最终用户”来说,NULL与空字符串问题是一种区别,没有必要和混淆点。

答案 6 :(得分:4)

NULL无法使用比较运算符与任何值进行比较。 NULL = NULL为false。 Null不是一个值。 IS运算符专门用于处理NULL比较。

答案 7 :(得分:4)

我只是没有看到空值的功能和无缝原因无法与其他值或其他空值相比,因为我们可以清楚地比较它并说它们在我们的上下文中是相同的或不相同的。这很有趣。仅仅因为一些合乎逻辑的结论和一致性,我们需要不断努力。它不具有功能性,使它更具功能性,让它留给哲学家和科学家来总结它是否一致,是否具有普遍逻辑&#34;。 :)有人可能会说它是因为索引或其他东西,我怀疑这些东西不能用于支持与值相同的空值。它与比较两个空眼镜相同,一个是藤玻璃,另一个是啤酒杯,我们不是比较对象的类型,而是比较它们包含的值,就像比较int和varchar一样,将它与null无关。更简单,没有什么,两个虚无有什么共同之处,它们是相同的,可以由我和其他所有写sql的人清楚地比较,因为我们通过比较它们以奇怪的方式不断打破这种逻辑,因为一些ANSI标准。为什么不使用计算机电源为我们做这件事,我怀疑如果所有相关内容都考虑到这一点,它会减慢速度。 &#34;它不是空的它没什么&#34;它不是苹果它的apfel,来吧......功能上是你的朋友,这里也有逻辑。最后,唯一重要的是功能,并且以这种方式使用空值会带来或多或少的功能和易用性。它更有用吗?

考虑以下代码:

SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end

你们中有多少人知道这段代码会返回什么?有或没有NOT它返回0.对我来说,这是不起作用的,它令人困惑。在c#中它应该是全部,比较操作返回值,逻辑上这也产生价值,因为如果它没有比较(没有什么:))。他们只是&#34;说&#34;:任何与null相比的东西&#34;返回&#34; 0,这会产生许多变通方法和头痛。

这是让我来到这里的代码:

where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)

我只需要比较两个字段(在哪里)有不同的值,我可以使用函数,但是......

答案 8 :(得分:1)

旧问题,但以下内容可能会提供更多细节。

null表示没有值或未知值。它没有指定为什么没有值,这可能导致一些歧义。

假设您运行如下查询:

SELECT *
FROM orders
WHERE delivered=ordered;

也就是说,您正在寻找ordereddelivered日期相同的行。

当一列或两列为空时会发生什么?

由于至少有一个日期未知,因此您不能指望两个日期相同。 两个日期都是未知的情况也是如此:如果我们甚至不知道它们是什么,它们怎么能相同呢?

因此,任何将null视为值的表达式都必须失败。在这种情况下,它将不匹配。如果您尝试以下操作也是如此:

SELECT *
FROM orders
WHERE delivered<>ordered;

同样,如果我们不知道它们是什么,我们怎么能说两个值相同。

SQL对缺失值进行了特定测试:

IS NULL

具体而言,它不是比较值,而是寻找缺少值。

最后,关于!=运算符,据我所知,它实际上并不属于任何标准,但它得到了广泛的支持。它被添加到一些语言的程序员感觉更多在家里。坦率地说,如果程序员难以记住他们正在使用的语言,那么他们的开始就会很糟糕。

答案 9 :(得分:0)

NULL不是任何东西......它是未知的。 NULL不等于任何东西。这就是为什么你必须在SQL查询中使用神奇短语IS NULL而不是= NULL

您可以参考:http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx

答案 10 :(得分:-1)

我想建议我这个代码来查找值是否有变化, 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的使用使其兼容各种类型