SQL Server 2012和NULL比较

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但我简化它们以显示问题所在.我认为它有操作顺序,但似乎不是它.

Gar*_*thD 7

我知道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)

在此输入图像描述