首页/数据/SQL 速查/NULL 三值逻辑与运算表现

NULL 三值逻辑与运算表现

NULL 参与比较得到 UNKNOWN、参与算术得到 NULL、参与字符串拼接通常也得到 NULL;理解这些规则才能写对过滤与统计。

SQL 速查数据更新于 2026-10-13

NULL 的语义是什么

NULL 表示未知。掌握它的几条规则就能避免大量隐蔽问题:参与比较得到 UNKNOWN(既不是 TRUE 也不是 FALSE),参与算术得到 NULL,参与字符串拼接在 MySQL 里得到 NULL、在 PostgreSQL 的 concat 函数里被忽略、用 || 运算符时得到 NULL。聚合函数除 COUNT(*) 外都忽略 NULL 输入。唯一索引中的多个 NULL 通常视为互不冲突。GROUP BY 会把多个 NULL 归为同一组,但 WHERE col = NULL 取不出这一组。

基本信息

三值逻辑TRUE、FALSE、UNKNOWN;WHERE 只保留 TRUE
比较NULL 参与任何比较都得 UNKNOWN
算术NULL 参与运算结果为 NULL
拼接MySQL 的 CONCAT 得 NULL;PG 的 concat 忽略,|| 得 NULL
聚合除 COUNT(*) 外都忽略 NULL 输入
唯一索引多个 NULL 通常不互斥
分组多个 NULL 归为同一组

典型使用场景

  • 排查查询结果为空:检查条件里是否混入 NULL 比较
  • 统计口径核对:COUNT(*) 与 COUNT(col) 的差异来源
  • 默认值设计:决定用 NULL 还是用默认值表示未填
  • 唯一约束设计:确认是否允许重复的 NULL
  • 分组观察数据质量:NULL 归组时暴露缺失分布
  • 跨库迁移核对:字符串拼接与聚合的 NULL 行为差异

行为演示

行为演示
SELECT NULL = NULL;            # UNKNOWN,不是 TRUE
SELECT NULL <> NULL;           # UNKNOWN
SELECT NULL + 1;               # NULL
SELECT CONCAT('a', NULL);      # MySQL:NULL
SELECT 'a' || NULL;            # PostgreSQL:NULL
SELECT concat('a', NULL);      # PostgreSQL:忽略 NULL,得到 a
SELECT NULL IS NULL;           # TRUE

NULL 在各处的表现

位置表现实践建议
比较运算得到 UNKNOWN判空用 IS NULL
算术运算结果为 NULL先用 COALESCE 兜底
字符串拼接MySQL 得 NULL,PG 的 concat 忽略统一用 COALESCE 兜底
聚合函数忽略 NULL 输入口径上明确 NULL 是否计入
GROUP BY多个 NULL 归为一组需要单独看缺失分布时很有用
唯一索引多个 NULL 并存需要强唯一时额外加约束
PostgreSQL 的 concat() 函数忽略 NULL 参数,而 || 运算符遇到 NULL 返回 NULL,函数与运算符行为不一致,迁移时逐条核对。
统计平均值时 AVG(col) 的分母是非 NULL 行数,与 SUM(col) 除以 COUNT(*) 的结果不同,按业务口径选择并写明。
WHERE 里的 <>、NOT IN、NOT LIKE 都会把 NULL 行排除在外,需要把缺失行也算进来时必须显式补 OR col IS NULL。

使用要点

  • 建模时先定每个列的可空性,关键字段加 NOT NULL
  • 决定用 NULL 还是默认值表示未填,全库统一
  • 判空一律用 IS NULL 与 IS NOT NULL
  • 聚合口径写清楚:是否把 NULL 行算进总数
  • 跨库迁移时核对拼接与聚合的 NULL 行为差异
  • 在数据质量报表里单独跟踪 NULL 比例的变化趋势

易错点

  • 统计平均值时 AVG(col) 的分母是非 NULL 行数,与 SUM(col) 除以 COUNT(*) 结果不同,按业务口径选择
  • GROUP BY 会把 NULL 分成一组,但 WHERE col = NULL 取不出这组,需用 IS NULL
  • 用 <> 或 NOT IN 过滤时把 NULL 行一起排除,结果比预期少且不易察觉
  • 不同数据库的字符串拼接对 NULL 的处理不一致,跨库迁移后结果悄悄变化
  • 把 NULL 与空串当作同一含义处理,导致统计与去重口径混乱

数据来源与参考

  • MySQL 8.0 Reference Manual · Working with NULL Values
  • PostgreSQL Documentation · Null Values
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌