有人可以解释一下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)
Answers:
<>
是标准SQL-92;!=
是等效的。两者都评估值,但NULL
不是- NULL
是占位符,表示不存在值。
这就是为什么您只能在此类情况下使用IS NULL
/ IS NOT NULL
作为谓词的原因。
此行为不特定于SQL Server。所有符合标准的SQL方言都以相同的方式工作。
注意:要比较如果您的值不为null,请使用IS NOT NULL
,而要与不为null值进行比较,请使用<> 'YOUR_VALUE'
。我不能说我的值是否等于NULL,但是我可以说我的值是NULL还是NOT NULL。如果我的值不是NULL,则可以进行比较。
!=
据我所知,直到〜i才支持Oracle ,这带来了许多ANSI-92语法。我相信MySQL是相似的,从4.x开始支持。
!=
着以后的规范中可能包含替代的<>
。不要动手掌握新规格,所以我不能肯定地说。
WHERE MyColumn != NULL
还是WHERE MyColumn = NULL
确定性的?换句话说,不管MyColumn
数据库中是否可以为空,是否保证总是返回0行?
!=
仅求值,因此执行类似操作WHERE MyColumn != 'somevalue'
不会返回NULL记录。
NULL没有值,因此无法使用标量值运算符进行比较。
换句话说,没有值可以等于(或不等于)NULL,因为NULL没有值。
因此,SQL具有特殊的IS NULL和IS NOT NULL谓词来处理NULL。
'a' != null
不返回值(true
/ 1
)是反直观的,并且会不时地吸引我!我本以为“一些价值与没有价值相比”永远都是“不平等”,但也许那只是我吗?!
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
如果为常量值x提供适当的数据类型(在本例中为字符串/字符),则通常可以分配一个常量(如果它是NULL值)。这是TSQL语法,但是Oracle和其他引擎具有类似的功能。
请注意,此行为是默认(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
)中添加WHERE子句,可以在SQL Server索引中获得重复的NULL :msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
为OFF时,等于(=)和不等于(<>)比较运算符不遵循ISO标准。使用的SELECT语句WHERE column_name = NULL
返回column_name中具有空值的行。使用SELECT语句WHERE column_name <> NULL
返回该列中具有非空值的行。同样,使用的SELECT语句WHERE column_name <> XYZ_value
返回所有不是XYZ_value且不是NULL的行。恕我直言,最后一条语句从结果中排除了空值,这似乎有些奇怪!
在SQL中,您对NULL
结果进行评估/计算的任何结果都为未知
这就是为什么SELECT * FROM MyTable WHERE MyColumn != NULL
或SELECT * FROM MyTable WHERE MyColumn <> NULL
给您0个结果。
为了提供对NULL
值的检查,提供了isNull函数。
此外,您可以IS
像在第三个查询中一样使用运算符。
希望这可以帮助。
唯一的NULL测试是IS NULL或IS NOT NULL。测试相等性是没有意义的,因为根据定义,人们不知道值是多少。
这是要阅读的维基百科文章:
我只是看不到null不能与其他值或其他null相提并论的功能性和无缝原因,因为我们可以清楚地比较它并说它们在我们的上下文中是相同还是不同。这很有趣。仅仅由于一些合理的结论和一致性,我们需要不断地对其进行打扰。它不是功能性的,要使其更具功能性,然后让哲学家和科学家们来断定它是否一致,并且是否具有“通用逻辑”。:)有人可能会说这是由于索引或其他原因造成的,我怀疑这些东西是否不能支持与值相同的null。就像比较两个空杯子,一个是藤蔓玻璃,另一个是啤酒杯,我们不是在比较对象的类型,而是它们包含的值,就像可以比较int和varchar一样,将其为null。甚至更容易,没有什么和两个虚无的共同点是什么,它们是相同的,对于我和其他编写sql的人来说,它们显然是可比较的,因为由于某些ANSI标准,我们不断以奇怪的方式比较它们来打破这种逻辑。为什么不使用计算机功能为我们做到这一点,我怀疑如果考虑到所有相关内容,它会减慢速度。“这不是null,什么也不是”,不是苹果,而是apfel,加油...功能上是您的朋友,这里也有逻辑。最后,唯一重要的是功能,并且确实以这种方式使用null会带来或多或少的功能和易用性。它更有用吗?因为我们由于某些ANSI标准而不断以奇怪的方式进行比较来打破这种逻辑。为什么不使用计算机功能为我们做到这一点,我怀疑如果考虑到所有相关内容,它会减慢速度。“这不是null,什么也不是”,不是苹果,而是apfel,加油...功能上是您的朋友,这里也有逻辑。最后,唯一重要的是功能,并且确实以这种方式使用null会带来或多或少的功能和易用性。它更有用吗?因为我们由于某些ANSI标准而不断以奇怪的方式进行比较来打破这种逻辑。为什么不使用计算机功能为我们做到这一点,我怀疑如果考虑到所有相关内容,它会减慢速度。“这不是null,什么也不是”,不是苹果,而是apfel,加油...功能上是您的朋友,这里也有逻辑。最后,唯一重要的是功能,并且确实以这种方式使用null会带来或多或少的功能和易用性。它更有用吗?不是苹果,它是apfel,来吧...从功能上来说是您的朋友,这里也有逻辑。最后,唯一重要的是功能,并且确实以这种方式使用null会带来或多或少的功能和易用性。它更有用吗?不是苹果,它是apfel,来吧...从功能上来说是您的朋友,这里也有逻辑。最后,唯一重要的是功能,并且确实以这种方式使用null会带来或多或少的功能和易用性。它更有用吗?
考虑以下代码:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
你们当中多少人知道这段代码会返回什么?不管是否带有NOT,它都返回0。对我来说,它不起作用并且令人困惑。在c#中,它应该是全部,比较操作返回值,从逻辑上讲,这也会产生值,因为如果没有,则没有什么可比较的(nothing :)除外)。他们只是“说”:与null相比,任何东西都“返回” 0,这会造成许多变通方法和麻烦。
这是使我来到这里的代码:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
我只需要比较两个字段(在哪里)具有不同的值,就可以使用函数,但是...
NULL无法使用比较运算符与任何值进行比较。NULL = NULL为假。Null不是值。IS运算符专门用于处理NULL比较。
null = null
可能使用的地方时,我总是很困惑1=0
。如果他们抱怨,我将其更改为null != null
:)
旧问题,但以下内容可能会提供更多详细信息。
null
表示无值或未知值。它没有说明为什么没有价值,这会导致一些歧义。
假设您运行如下查询:
SELECT *
FROM orders
WHERE delivered=ordered;
也就是说,您正在寻找ordered
和delivered
日期相同的行。
一列或两列为空时会发生什么?
因为至少一个日期是未知的,所以您不能期望说这两个日期是相同的。当两个日期都不知道时也是如此:如果我们什至不知道它们是什么,它们怎么可能相同?
因此,任何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
有不同的含义; 它并不代表未知的事物,而是有意重置的值。SQL并非如此。
IS NULL
AND 之间没有开销=NULL
。但是,请看一下Hover的最后一个。我厌倦了一次又一次的体验,不得不做不必要的负担?额外的检查...
我想建议我编写的这段代码,以查找值是否有所变化,
i
是新值还是d
旧值(尽管顺序无关紧要)。因此,从值更改为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不等于任何东西。这就是为什么您必须在SQL查询中使用魔术短语IS NULL而不是= NULL的原因
您可以参考以下网址:http : //weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
在92规范中,但是大多数供应商都支持!=
和/或它包含在更高的规范中,例如99或03。–