PostgreSQL NULL 值详解

在 PostgreSQL 中,NULL
代表 未知值或缺失值,而不是空字符串 (''
) 或 0
。在数据库操作中,NULL
需要特殊处理,因为它的行为与普通值不同。
1. NULL 的基本概念
NULL
不是 一个具体的值,而是“没有值”。- 不能用
=
或!=
比较NULL
,需要使用IS NULL
或IS NOT NULL
进行判断。
示例
SELECT NULL = NULL; -- 结果:NULL(不是 TRUE 也不是 FALSE)
SELECT NULL <> NULL; -- 结果:NULL
SELECT NULL IS NULL; -- 结果:TRUE
SELECT NULL IS NOT NULL; -- 结果:FALSE
2. 在表中使用 NULL
创建包含 NULL
值的表:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INTEGER
);
插入数据:
INSERT INTO students (name, age) VALUES ('Alice', 20);
INSERT INTO students (name, age) VALUES ('Bob', NULL);
INSERT INTO students (name, age) VALUES ('Charlie', 25);
查询包含 NULL
的数据:
SELECT * FROM students;
结果:
id | name | age |
---|---|---|
1 | Alice | 20 |
2 | Bob | NULL |
3 | Charlie | 25 |
3. NULL 的比较与判断
(1) IS NULL / IS NOT NULL
用来检查 NULL
值:
SELECT * FROM students WHERE age IS NULL;
结果:
id | name | age |
---|---|---|
2 | Bob | NULL |
如果想查询 非 NULL 的值:
SELECT * FROM students WHERE age IS NOT NULL;
(2) COALESCE()
COALESCE()
函数用于 替换 NULL 值,返回第一个非 NULL
值:
SELECT name, COALESCE(age, 18) AS age FROM students;
结果:
name | age |
---|---|
Alice | 20 |
Bob | 18 |
Charlie | 25 |
(3) NULLIF()
NULLIF(value1, value2)
:如果 value1 = value2
,返回 NULL
,否则返回 value1
。
SELECT NULLIF(10, 10); -- 结果:NULL
SELECT NULLIF(10, 20); -- 结果:10
4. NULL 在计算中的影响
NULL
参与计算时,结果仍为NULL
。
SELECT 10 + NULL; -- 结果:NULL
SELECT NULL * 5; -- 结果:NULL
- 使用
COALESCE()
避免 NULL 影响计算:
SELECT name, COALESCE(age, 0) * 2 AS double_age FROM students;
5. NULL 在聚合函数中的影响
COUNT(*)
计算所有行,包括NULL
值。COUNT(column)
不计算NULL
值。
SELECT COUNT(*) FROM students; -- 结果:3
SELECT COUNT(age) FROM students; -- 结果:2
- 其他聚合函数如
SUM()
、AVG()
、MIN()
、MAX()
也会忽略NULL
值:
SELECT AVG(age) FROM students; -- 结果:(20+25)/2 = 22.5
SELECT SUM(age) FROM students; -- 结果:45
6. NULL 在 ORDER BY 排序中的影响
默认情况下,NULL
值在 ORDER BY ASC
时排在最后,在 ORDER BY DESC
时排在最前:
SELECT * FROM students ORDER BY age ASC;
如果想让 NULL
值排在最前,可以使用 NULLS FIRST
:
SELECT * FROM students ORDER BY age ASC NULLS FIRST;
7. NULL 在 JOIN 查询中的影响
在 JOIN
操作中,NULL
可能会影响匹配:
CREATE TABLE courses (
student_name VARCHAR(100),
course VARCHAR(50)
);
INSERT INTO courses VALUES ('Alice', 'Math'), ('Charlie', 'Physics');
SELECT students.name, students.age, courses.course
FROM students
LEFT JOIN courses ON students.name = courses.student_name;
结果:
name | age | course |
---|---|---|
Alice | 20 | Math |
Bob | NULL | NULL |
Charlie | 25 | Physics |
8. NULL 在 CHECK 约束中的处理
创建表时可以使用 CHECK
限制 NULL
处理:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary INTEGER CHECK (salary > 0)
);
如果 salary
插入 NULL
,不会触发 CHECK
约束,因为 NULL
不是 > 0
也不是 <= 0
。
要避免这种情况,需要 salary
设置 NOT NULL
:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary INTEGER NOT NULL CHECK (salary > 0)
);
9. 处理 NULL 的最佳实践
- 使用
COALESCE()
替换NULL
,避免NULL
影响计算。 - 使用
IS NULL
/IS NOT NULL
进行判断,不要用=
。 - 在
ORDER BY
时注意NULL
的排序规则。 - 在
JOIN
查询中要考虑NULL
可能影响匹配结果。 - 在
CHECK
约束中要注意NULL
的特殊情况。
更多详细内容请关注其他相关文章!