我对以下原因的理由感到困惑:
SELECT * FROM table WHERE avalue is null
返回'avalue'为空的行数
SELECT * FROM table WHERE avalue <> true
不会返回'avalue'为空的行。
我的推理(看似不正确)是因为null
是唯一值(它甚至不等于null
)意味着它应该显示在结果集中,因为它不是也等于true
。
我想你可以说,通过说column <> value
你暗示该列有一个值,因此完全忽略null
值。
这背后的原因是什么,这在其他常见的SQL DB中是一样的吗?
我的推理(假设)告诉我这是违反直觉的,我想了解原因。
答案 0 :(得分:34)
每个中途不错的RDBMS以相同的方式完成它,因为它正确。
我引用了the Postgres manual here:
普通比较运算符产生null(表示“未知”),而不是 当任一输入为空时,为true或false。例如,
7 = NULL
会产生 null,7 <> NULL
也是如此。如果此行为不合适,请使用IS [ NOT ] DISTINCT FROM
构造:expression IS DISTINCT FROM expression expression IS NOT DISTINCT FROM expression
请注意,这些表达式的执行速度比简单的expression <> expression
比较慢。
对于boolean
值,还有更简单的IS NOT [TRUE | FALSE]
要获得您在第二个查询中的预期,请写下:
SELECT * FROM table WHERE avalue IS NOT TRUE;
答案 1 :(得分:6)
This link提供了有用的见解。正如@Damien_The_Unbeliever指出的那样,它使用三值逻辑,并且似乎(根据文章)是辩论的主题。
我认为归结为null不是一个值,而是一个值的占位符,必须做出决定,这就是它......所以NULL不等于任何值,因为它不是价值,甚至不等于任何价值......如果这是有道理的。
答案 2 :(得分:2)
这很正常。 SQL Server以相同的方式完成它。在SQL Server中,您可以使用
SELECT * FROM table WHERE ISNULL(avalue, 0) <> 1
对于postgresql等效,请观看:What is the PostgreSQL equivalent for ISNULL()
如果有意义,请考虑使用带有默认值的NOT NULL列规范。
编辑:
我认为这是逻辑。 NULL不是值,因此它从搜索中排除 - 您必须明确指定它。如果SQL设计者决定采用第二种方式(自动包含空值),那么如果您不需要识别值,则会遇到更多麻烦