📄 一句话概括
NULL 不是 0、不是空字符串,而是「这里没有值」——一个占着位置的空。它是全章最反直觉的概念,两条铁律必须刻进脑子:= NULL 永远查不到任何东西;NULL 参与算术,结果也是 NULL。
📝 本节和前面几节的关系
上一节 DEFAULT 提到:显式写 NULL 会绕过默认值。本节把 NULL 本身讲透——第三章 3-10 已经埋过「= NULL 查不到、必须用 IS NULL」的伏笔,这里补齐为什么,并看清 NULL 对聚合函数(3-15~3-17 的 COUNT/AVG)的暗中影响。
一、NULL 是「未知」,不是「零」
三个东西要分清:
| 值 | 含义 | 例子 |
|---|---|---|
0 |
有值,值为零 | 考了 0 分 |
'' |
有值,空字符串 | 名字填了但一个字没写 |
NULL |
没有值 | 还没考试,成绩未知 |
把「未知」当成 0,统计就全毁了:3-17 里钱七 score 为 NULL,AVG 的分母是 4 不是 5——NULL 不参与计算,这正是它诚实的表现。
二、NULL 的传染性:算术里见谁传谁
任何数和 NULL 做算术,结果都是 NULL:
NULL + 1 -- NULL
5 * NULL -- NULL
逻辑也同理:NULL > 0 的结果不是真也不是假,而是未知(三值逻辑:真/假/未知)。这就是为什么:
WHERE score = NULL→ 一行都不返回(拿「未知」去比,比不出确定答案)WHERE score IS NULL→ 正确写法,专测「是不是没有值」
三、NULL 与比较函数
| 写法 | 结果 |
|---|---|
score = NULL |
永远未知 → 查不到 |
score IS NULL |
判定是否无值 ✅ |
score IS NOT NULL |
判定是否有值 |
IFNULL(score, 0) |
NULL 时换成 0(SQLite 同款) |
四、动手 Demo:三值逻辑亲手验
沿用贯穿表(钱七 score 为 NULL):
CREATE TABLE students (
id INT,
name VARCHAR(20),
score DECIMAL(5,2)
);
INSERT INTO students VALUES (1,'张三',85),(2,'李四',92),(3,'王五',78),(4,'赵六',88),(5,'钱七',NULL);
-- 1. 错误写法:一行都查不到
SELECT * FROM students WHERE score = NULL;
-- 2. 正确写法:抓出没成绩的人
SELECT * FROM students WHERE score IS NULL;
-- 3. AVG 的分母不含 NULL
SELECT AVG(score) FROM students; -- 85.75,分母是 4 不是 5
-- 4. NULL 传染:给钱七加 10 分也加不动
SELECT name, score + 10 AS 加分后 FROM students WHERE id = 5; -- 加分后 = NULL
五、30 秒实验
执行 SELECT COUNT(score) FROM students 和 SELECT COUNT(*) FROM students——前者 4(跳过 NULL),后者 5(只数行数)。COUNT 一字之差,答案不同。
六、常见误区
- 「NULL 就是 0」:0 是有值;NULL 是没值。AVG 会把前者算进去、把后者排除
- 「IS NULL 是可换可不换的写法」:
= NULL是逻辑死路(永远未知),不是「效果差一点」 - 「列里少数据就填 0 好了」:0 会混进 AVG/MIN/MAX 的正常统计;「没值」就老实存 NULL
自测三问
1. NULL、0、空字符串三者区别?(没值/值为零/有值但空) 2. 为什么 `= NULL` 查不到?(NULL 参与比较结果是未知,三值逻辑) 3. AVG 分母怎么算 NULL?(不参与,分母只数有值行)- ☐ 下一节(4-9 NOT NULL-避免数据为空的状态)
相关笔记
- DEFAULT-设置默认值 —— 上一节:缺省时给值还是给 NULL
- COUNT函数-获取记录的数量 —— COUNT(score) 与 COUNT(*) 差的那一行
- SUM函数、AVG函数-获取记录的合计值和平均值 —— AVG 分母之谜的答案
- 🗄️ 数据库基础 · 索引 —— 全课路线图