NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值。数据表中的 NULL 值表示该值所处的字段为空,值为 NULL 的字段没有值,尤其要明白的是:NULL 值与 0 或者空字符串是不同的。
在 SQL 中却存在第三个逻辑值:true,false,unknown。
逻辑值unknown和作为NULL的一种的UNKNOWN(未知)是不同的东西。前者是明确的布尔型的逻辑值,后者既不是值也不是变量。为了便于区分,前者采用小写字母unknown,后者用大写字母UNKNOWN 来表示。为了让大家理解两者的不同,我们来看一个x=x这样的简单等式。x是逻辑值unknown时,x=x被判断为true,而x是UNKNOWN时被判断为unknown。
为什么必须写成“IS NULL”,而不是“= NULL”?
对NULL使用比较谓词后得到的结果总是unknown而查询结果只会包含WHERE子句里的判断结果为true的行,不会包含判断结果为false和unknown的行。不只是等号,对NULL使用其他比较谓词,结果也都是一样的。所以无论remark是不是NULL,比较结果都是unknown,那么永远没有结果返回。以下的式子都会被判为unknown:
= NULL
> NULL
< NULL
<> NULL
NULL = NULL
NULL 容易被认为是值的原因有两个。第一个是高级编程语言里面,NULL 被定义为了一个常量(很多语言将其定义为了整数0),这导致了我们的混淆。但是,SQL 里的 NULL 和其他编程语言里的 NULL 是完全不同的东西。第二个原因是,IS NULL 这样的谓词是由两个单词构成的,所以我们容易把 IS 当作谓词,而把 NULL 当作值。特别是 SQL 里还有 IS TRUE 、IS FALSE 这样的谓词。
如果 NOT IN 子查询中用到的表里被选择的列中存在 NULL ,则 SQL 语句整体的查询结果永远是空。这是很可怕的现象!
IN 和 EXISTS 可以互相替换使用,而 NOT IN和 NOT EXISTS 却不可以互相替换的混乱现象。
IS NULL 整个是一个谓词,而不是:IS 是谓词,NULL 是值;类似的还有 IS TRUE、IS FALSE
参考文献
神奇的 SQL 之温柔的陷阱 → 三值逻辑 与 NULL !
SQL三值逻辑和NULL
那些年我们踩过的坑,SQL 中的空值陷阱!
12.3 操作符
网友评论