首页/数据/数仓建模速查/度量 NULL 与 0 的语义
维度与事实设计149 条

度量 NULL 与 0 的语义

NULL 表示未知/不适用,0 表示真实发生的零值:两者混用会让平均值、占比与覆盖率全部失真,入仓时要显式区分。

数仓建模速查数据更新于 2026-10-13

NULL 与 0 的差别

NULL 表示未知、未发生或源系统没有提供,0 表示业务上真实发生且取值为零,两者语义完全不同。混用会让平均值、占比与覆盖率同时失真:聚合函数默认忽略 NULL,一旦用 coalesce 统一填零,就把「没有发生」变成了「发生了但为零」。正确做法是在明细层完整保留 NULL,把补零只当展示约定处理,并在指标卡里写清分母用的是非空样本还是全量行数。

基本信息

NULL未知、未发生或源未提供
0业务上真实发生的零值
受影响指标平均值、占比、非空率、覆盖率
处理原则明细保留 NULL,展示层单独约定
校验总行数、空值数、零值数分开统计

典型使用场景

  • 区分「当日无销售」与「当日销售额为零」,两者在波动检测里含义不同
  • 覆盖率类指标(有手机号的客户占比)必须用非空计数做分子
  • 质量巡检把空值率与零值率分开看,避免把缺失当成业务下滑
  • 上游用空字符串或特殊编码表示缺失时,在接入层统一转成 NULL
  • 报表补零展示前,先确认下游口径是否需要保留缺失信息

分开统计三类

分开统计三类
-- 全量行、空值、零值分开统计,语义一目了然
SELECT count(1) AS rows_all,
       sum(CASE WHEN amt IS NULL THEN 1 ELSE 0 END) AS rows_null,
       sum(CASE WHEN amt = 0 THEN 1 ELSE 0 END)    AS rows_zero,
       avg(amt) AS avg_non_null,
       sum(amt) / count(1) AS avg_with_zero
FROM dwd_order
WHERE dt = '2026-10-12';

四种情况对照

取值含义用错的表现
NULL未知或未发生填零后平均值被拉低
0发生且取值为零被当缺失剔除后指标虚高
空字符串常见于源系统导出关联匹配不到,产生伪缺失
-1 等占位值源系统特殊编码参与计算后出现极端离群
avg 与 sum 都会忽略 NULL,但除法的分母不会自动忽略,所以「sum 除以全量行数」和「sum 除以非空行数」是两个不同的数,必须提前约定用哪一个。
把 NULL 显示为 0 是展示层约定,不要直接在明细表里改写,否则后续无法回溯究竟有多少条数据是缺失的。

易错点

  • 用 coalesce 一把梭把 NULL 全填零,缺失与零值永久混为一谈
  • 空字符串未在接入层转 NULL,关联匹配失败产生伪缺失
  • 覆盖率指标用全量行数做分母,未知被当成没有
  • 空值率不监控,上游接口变更造成的缺失长期无人发现

数据来源与参考

  • SQL 标准与各引擎聚合语义;数据仓库工具箱
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌