我们有一个列(我们称之为status
),可以是NULL
,processing
或closed
。
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的行为吗?
答案 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 NULL
或IS 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 null
和is 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
你无法检查是否存在平等,不平等,重要,等于,等等。