在使用MySQL时,我注意到如果运行
SELECT * FROM table WHERE !value;
返回与相同的内容
SELECT * FROM table WHERE value IS NOT NULL;
表是"employees",列是"MiddleInitial"(字符串),所以我得到所有MiddleInitial不为空的雇员。
这是一个正确的速记还是只是一个巧合?我想知道这是否是一个安全的写作方式?我似乎找不到任何有关这方面的信息。
我还以为
SELECT * FROM table WHERE !value;
返回所有空值。奇怪的是
SELECT * FROM table WHERE value;
不返回任何内容。
2条答案
按热度按时间nue99wik1#
不,不是的。
这看起来像是因为它正在进行类型强制,将列中的任何内容强制为布尔值。当强制为boolean predicate时,
NULL
值将强制为false
,并且大多数非空列值将强制为true
。但是一些列值(非空)也将强制为false
。您可以在这里看到示例:
https://dbfiddle.uk/ABLUgLex
注意,最后一个示例缺少
0
行,另外注意,前面的示例不包括null
行,这使我怀疑您的服务器可能设置了一个用于非标准空处理的选项。下面是一些示例:
https://dbfiddle.uk/BNxiujKt
请注意对
'1'
行的处理。zz2j4svz2#
在SQL中,
NULL
与false
不同。否定
NULL
就不是true
,它仍然是NULL
。把
NULL
看作是“unknown”,如果某个信息是未知的,那么它的对立面怎么可能是已知的呢?不可能--对立面也是未知的,因为我们不知道我们从哪里开始的。在
WHERE
子句条件中使用NULL
时,NULL
的行为或多或少类似于false
,因为两者都不是严格意义上的true
。只有条件为true
的行才会成为查询结果集的一部分。在MySQL中还有其他类似
false
的值:MySQL有点不标准,因为布尔值
true
和false
在字面上分别与整数值1和0相同(这不是大多数其他品牌的SQL数据库实现布尔的方式)。这些值不是
NULL
,因此它们可以取反,您可以将它们的对立面视为true
。正如上面的评论所说,
!
运算符在MySQL 8.0中已被弃用。它不是标准SQL,使用它会使代码不如使用IS NOT NULL
或<>
等更显式的语言清晰。