数据稀疏度指某列在各分组内非空有效值占比低,需按组用COUNT(*)作分母、CASE显式判断有效值(如IS NOT NULL且TRIM!='')作分子计算,不可直接用COUNT(col)。

什么是“数据稀疏度”在分组统计里的实际含义
SQL 中没有叫 DENSITY 或 SPARSITY 的内置函数,所谓“稀疏度”,业务上通常指:**某列在每个分组内非空值占比低、大量为 NULL 或默认空值(如 ''、0)**。它不是数学密度,而是对数据填充质量的直观判断。
关键点在于:必须按分组计算,且要区分 NULL 和空字符串——很多误用把 COUNT(col) 当成“非空计数”,却忘了 COUNT() 本身就会跳过 NULL,但不会跳过 '';而 COUNT(*) 统计所有行,不管字段是否为空。
用 COUNT + CASE 算每组非空比例(最通用写法)
核心逻辑是:分母用 COUNT(*)(该组总行数),分子用显式条件判断哪些算“有效值”。不能依赖 COUNT(col) 直接替代,尤其当列允许空字符串或零值时。
-
COUNT(*)是安全分母,不遗漏任何行 - 分子推荐写成
COUNT(CASE WHEN col IS NOT NULL AND TRIM(col) != '' THEN 1 END)(文本列) - 数值列若把
0视为无效,就得加AND col != 0,否则0会被计入“非空” - MySQL 8.0+ / PostgreSQL / SQL Server 都支持,无兼容性风险
示例:统计各 dept 下 email 字段的非空比例
SELECT dept, COUNT(*) AS total, COUNT(CASE WHEN email IS NOT NULL AND TRIM(email) != '' THEN 1 END) AS non_empty_cnt, ROUND(100.0 * COUNT(CASE WHEN email IS NOT NULL AND TRIM(email) != '' THEN 1 END) / COUNT(*), 2) AS non_empty_pct FROM employees GROUP BY dept;
为什么不能直接用 COUNT(email) / COUNT(*)
看起来简洁,但隐患明显:
-
COUNT(email)只跳过NULL,不处理''(空字符串)、' '(纯空格)、'null'(字符串字面量) - 如果业务定义“邮箱为空字符串即无效”,那
COUNT(email)就高估了真实可用率 - 某些 ETL 流程会把缺失值补成
'N/A'或'UNKNOWN',这时COUNT(email)完全失效 - 聚合后无法还原原始语义:你不知道是
NULL多,还是脏字符串多
稀疏度高时的后续动作建议
发现某组 non_empty_pct < 10%,别急着删数据。先确认:
- 该列是否本就属于可选字段(如“员工紧急联系人电话”)?业务上允许大量为空
- 空值集中在某个子类(如
dept = 'Intern'),可能反映录入规则差异,而非质量问题 - 是否因上游系统未同步导致批量
NULL?需查变更日志,而非仅看快照 - 若真要清洗,优先用
UPDATE ... SET col = NULL WHERE TRIM(col) IN ('', 'N/A', 'NULL')统一归零,再走标准空值处理流程
真正容易被忽略的是:稀疏度指标本身需要和业务上下文绑定。同一列在销售表里 95% 空是异常,在历史归档表里 95% 空可能是正常状态。

















