在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,因为NULL没有值。

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

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

如果你:

  SET ANSI_NULLS OFF 

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

你会得到不同的结果。

SET ANSI_NULLS OFF将显然将在未来…

在SQL中,任何您使用NULL计算/计算的结果都会导致UNKNOWN

这就是为什么SELECT * FROM MyTable WHERE MyColumn != NULLSELECT * FROM MyTable WHERE MyColumn <> NULL给你0结果。

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

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

希望这可以帮助。

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

唯一的NULLtesting是IS NULL或IS NOT NULL。 testing平等是无意义的,因为根据定义,人们不知道价值是什么。

这里是一个维基百科文章阅读:

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

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

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

我只是没有看到空值不能与其他值或其他空值相比的function和无缝的原因,因为我们可以清楚地比较它,并说它们是相同的或不在我们的上下文中。 这很有趣。 正因为有一些合乎逻辑的结论和一致性,我们需要不断地打扰它。 它不是function性的,使其function更强大,让哲学家和科学家们断定它是否一致,是否具有“普遍逻辑”。 :)有人可能会说,这是因为索引或其他什么东西,我怀疑这些东西不能支持空值相同的值。 这与比较两个空杯子是一样的,一个是葡萄酒玻璃,另一个是啤酒杯,我们没有比较对象的types,但它们包含的值,可以比较int和varchar,与null相比,更容易,没有什么,什么也没有两个没有共同点,它们是相同的,由我和其他编写sql的人明显地相媲美,因为我们不断地通过一些ANSI标准以奇怪的方式来比较它们。 为什么不用计算机的力量为我们做这件事呢?我怀疑,如果所有相关的东西都是为了这个念头而构build的,那么这件事情就会减慢。 “它不是空的,它是没有的”,它不是苹果它apfel,来吧…function上是你的朋友,这里也有逻辑。 最后,唯一重要的就是function性,并且以这种方式使用空值会带来或多或less的function和易用性。 它更有用吗?

考虑这个代码:

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

你们有多less人知道这个代码会返回什么? 有或没有NOT它返回0.对我来说,这是不正常的,它是混乱。 在c#中它是所有的应该是,比较操作返回值,逻辑上这也产生价值,因为如果它没有什么比较(除了没有:))。 他们只是“说”:任何比较为零的“返回”0,并创造了许多解决方法和头痛。

这是把我带到这里的代码:

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

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

我们用

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

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

我想build议这个代码,我发现是否有一个值的变化, 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 

要使用这个function,你可以

 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 ---- ab = 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的使用使其兼容各种types