在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 != NULL
或SELECT * FROM MyTable WHERE MyColumn <> NULL
给你0结果。
为了提供NULL
值的检查,提供了isNull函数。
而且,您可以使用第三个查询中使用的IS
运算符。
希望这可以帮助。
NULL无法使用比较运算符与任何值进行比较。 NULL = NULL是假的。 空值不是一个值。 IS运算符专门用于处理NULL比较。
唯一的NULLtesting是IS NULL或IS NOT NULL。 testing平等是无意义的,因为根据定义,人们不知道价值是什么。
这里是一个维基百科文章阅读:
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