pen*_*en2 1 sql-server comparison null sql-server-2012
谁能解释一下为什么这两个陈述会返回不同的结果?
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
Run Code Online (Sandbox Code Playgroud)
我知道NULL与任何东西相比都会给出错误,我想使用那个属性,但是我停止了与上面类似的命令.我的真实语句而不是NULL使用可能的变量,NULL但我简化它们以显示问题所在.我认为它有操作顺序,但似乎不是它.
我知道NULL与任何东西相比都是假的
这是不正确的,NULL与任何评估为未知的,而不是虚假的,一个简单的例子相比:
SELECT CASE WHEN (NULL = NULL) THEN 'True'
WHEN NOT(NULL = NULL) THEN 'False'
ELSE 'Other'
END
Run Code Online (Sandbox Code Playgroud)
将给出第三种选择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
Run Code Online (Sandbox Code Playgroud)
所以在第一个例子中你有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
Run Code Online (Sandbox Code Playgroud)