小编典典

SQL:为什么在此where子句中过滤掉NULL值?

sql

在我的表中,我有一个可为空的bit列(旧系统…),另一位开发人员最近对存储过程进行了更改,以仅显示bit列不为真的值(1)。因为这是一个可为空的列,所以我们注意到,如果该列为NULL,则不会选择该记录。为什么是这样?

我和其他开发人员都同意NULL <> 1 …这是SQL中的错误还是设计这种方式?似乎是设计缺陷。

当前代码:

(VoidedIndicator <> 1)

建议的修复:

(VoidedIndicator <> 1 OR VoidedIndicator IS NULL)

澄清(由乔恩·埃里克森(Jon Erickson))

VoidedIndicator是一个可为空的位字段,因此它可以具有以下值:NULL,0或1

当使用诸如(VoidedIndicator <> 1)之类的where子句创建SQL语句时,我们仅返回具有VoidedIndicator ==
0的记录,但是我们期望VoidedIndicator == 0和VoidedIndicator IS NULL。为什么是这样?


阅读 230

收藏
2021-04-07

共1个答案

小编典典

Wikipedia条目上的NULL

例如,WHERE子句或条件语句可能会将列的值与常量进行比较。通常错误地认为,如果该字段包含Null,则缺失值将“小于”或“不等于”常量,但实际上,此类表达式返回Unknown。下面是一个示例:

-- Rows where num is NULL will not be returned,
-- contrary to many users' expectations.
SELECT * FROM sometable WHERE num <> 1;

基本上,NULL和其他 任何 东西之间的 任何 比较(无论是=还是<>)都将是不正确的。

作为另一参考,MSDN T-SQL页面上<>指出:

比较两个表达式(比较运算符)。比较非空表达式时,如果左操作数不等于右操作数,则结果为TRUE;否则,结果为TRUE。否则,结果为FALSE。如果一个或两个操作数均为NULL,请参见SET
ANSI_NULLS(Transact-SQL)。

SET ANSI_NULLS然后页指出:

当SET ANSI_NULLS为ON时,即使column_name中包含空值,使用WHERE column_name =
NULL的SELECT语句也将返回零行。即使column_name中包含非空值,使用WHERE column_name <>
NULL的SELECT语句也将返回零行。

当SET ANSI_NULLS设置为ON时,所有与空值的比较都将得出UNKNOWN。当SET
ANSI_NULLS为OFF时,如果数据值为NULL,则将所有数据与null值的比较评估为TRUE。

2021-04-07