任何人都可以解释为什么这两个陈述会返回不同的结果吗?
SELECT CASE WHEN NOT((NULL = NULL) OR (1 != 1)) THEN 1 ELSE 0 END
SELECT CASE WHEN NOT((NULL = NULL) AND (1 != 1)) THEN 1 ELSE 0 END
我知道NULL
与任何东西相比都是假的,我想要使用那个属性,但我停止了与上述类似的命令。我的真实语句而不是NULL使用可以NULL
的变量,但我简化它们以显示问题所在。我认为它与操作顺序有关,但似乎不是它。
答案 0 :(得分:7)
我知道NULL与任何东西相比都会给出错误的
这不正确,NULL
与任何评估未知的对比,而非虚假,快速示例:
SELECT CASE WHEN (NULL = NULL) THEN 'True'
WHEN NOT(NULL = NULL) THEN 'False'
ELSE 'Other'
END
将提供Other
的第三个选项。
如果我们重写你的逻辑(仍然是相同的含义,但它变得更清楚):
SELECT CASE WHEN (NULL <> NULL) AND (1 = 1) THEN 1 ELSE 0 END
SELECT CASE WHEN (NULL <> NULL) OR (1 = 1) THEN 1 ELSE 0 END
因此,在第一个实例中,WHEN [Unknown] AND [True]
为假,但在第二个实例中,WHEN [Unknown] OR [True]
为真,因此返回1.
如果使用变量重写查询,然后检查执行计划XML,您可以看到SQL Server在编译期间重写了上面的表达式:
DECLARE @a INT = NULL, @b INT = NULL, @c INT = 1, @d INT = 1;
SELECT TOP 1
CASE WHEN NOT((@a = @b) OR (@c != @d)) THEN 1 ELSE 0 END,
CASE WHEN NOT((@a = @b) AND (@c != @d)) THEN 1 ELSE 0 END
答案 1 :(得分:1)
-- first query
SELECT CASE WHEN NOT((NULL = NULL) AND (1 != 1)) THEN 1 ELSE 0 END
=
SELECT CASE WHEN NOT(unknown AND false) THEN 1 ELSE 0 END
=
SELECT CASE WHEN NOT(false) THEN 1 ELSE 0 END
=
SELECT CASE WHEN true THEN 1 ELSE 0 END
=
1
-- second query
SELECT CASE WHEN NOT((NULL = NULL) OR (1 != 1)) THEN 1 ELSE 0 END
=
SELECT CASE WHEN NOT(unknown OR false) THEN 1 ELSE 0 END
=
SELECT CASE WHEN NOT(unknown) THEN 1 ELSE 0 END
=
SELECT CASE WHEN unknown THEN 1 ELSE 0 END
=
else matched, so 0
来自评论的D0dger的问题:
为什么SELECT CASE WHEN(NULL = NULL)OR(1!= 1)THEN 1 ELSE 0 END和SELECT CASE WHEN NOT((NULL = NULL)OR(1!= 1))那么1 ELSE 0更有趣END返回0
SELECT CASE WHEN (NULL = NULL) OR (1 != 1) THEN 1 ELSE 0 END
=
SELECT CASE WHEN unknown OR false THEN 1 ELSE 0 END
=
SELECT CASE WHEN unknown THEN 1 ELSE 0 END
=
else matched, so 0
答案 2 :(得分:0)
因此,有两个选项:要么ANSI_NULLS开启(你应该),要么你有ANSI_NULLS OFF。
在第一种情况下,任何与NULL的比较都会返回NULL(甚至比如你的NULL值之间的比较)。
在第二种情况下,sql server将评估NULL值之间的比较(例如,NULL = NULL将返回true)。
因此,在考虑查询中的不同结果之前,您必须首先考虑将NULL与任何内容进行比较,并且不会将其评估为false但是