为什么WHERE(列)NOT(value)忽略where(column)为NULL?

时间:2016-01-20 21:28:49

标签: mysql

我们有一个列(我们称之为status),可以是NULLprocessingclosed

ID    | STATUS
------------------
1     | NULL
2     | NULL
3     | processing
4     | closed

我们构建此范围以查找未关闭的订单,它看起来像WHERE 'status' IS NOT 'closed'。但是,这会返回:

ID    | STATUS
------------------
3     | processing

这让我们感到困惑,因为我们预计会回来:

ID    | STATUS
------------------
1     | NULL
2     | NULL
3     | processing

我们通过复合WHERE 'status' IS NULL OR 'status' != 'closed'来解决这个问题。

很简单,但它仍然让我们感到困惑,因为这似乎并不直观。

我试着通过MySQL文档来解释这个问题,然后用Google搜索了一下,但是我无法筛选那些只是在讨论如何寻找不为空的问题/文档。我无法找到IS NOT x忽略NULL的原因的解释。

有人能指出我正确的方向吗?这是MySQL特有的东西,这是大多数SQL dbs的行为吗?

4 个答案:

答案 0 :(得分:1)

SQL中的大多数操作(IS NULL除外)在获得NULL时返回NULL。您可以将其视为“未定义”,并且输入未定义的任何操作的结果都会提供未定义的结果。这可能会变得非常混乱,例如在这种情况下:CONCAT('a', NULL, 'b')也会产生NULL

这不是特定于MySQL的。维基百科对此进行了长时间的讨论:https://en.wikipedia.org/wiki/Null_%28SQL%29

答案 1 :(得分:1)

很抱歉,但这不是NULL的工作方式。 NULL定义为在除IS NULLIS NOT NULL之外的任何比较中均不返回true。即使NULL = NULL返回FALSE。您可以使用COALESCE函数使代码更易于读写,例如

WHERE COALESCE(status,'') <> 'closed'

这种陌生感实际上是SQL标准的一部分,而不是MySQL问题。这是您不希望在状态等列中使用NULL值的原因之一。

答案 2 :(得分:1)

将任何内容与NULL进行比较会导致NULL(使用空操作符时除外)。当它在arecord中遇到空字段时,IS NOT 'closed'条款基本上就是这样做:

  NULL != 'closed'

如上所述,即使你认为这是一个真实的陈述,这将导致NULL被归还,在where条件中被视为false,因此记录不匹配并成为结果集。

您必须使用明确的is nullis not null运算符。

答案 3 :(得分:0)

Nulls不是普通值,在参考手册中是这样说的:

  

在您习惯之前,NULL值可能会令人惊讶。从概念上讲,NULL表示“缺少未知值”,并且与其他值的处理方式略有不同。

     

要测试NULL,请使用IS NULL和IS NOT NULL运算符

http://dev.mysql.com/doc/refman/5.7/en/working-with-null.html

你无法检查是否存在平等,不平等,重要,等于,等等。