在SQL数据处理工作中,按指定字段分组后统计组内目标字段的空值比例是常见需求,比如按部门统计员工邮箱字段的空值占比,按商品分类统计库存字段的空值占比等。这类需求可以通过COUNT函数和CASE WHEN条件表达式的组合快速实现,不需要复杂的嵌套查询。

核心实现逻辑
统计分组内空值比例的核心思路是分别计算两个数值,再做除法运算:第一个是分组内的总记录数,第二个是分组内目标字段为空值的记录数,空值比例等于空值记录数除以总记录数。
COUNT函数的特性是会自动忽略NULL值,而COUNT(*)会统计所有记录数,包括NULL值。结合CASE WHEN可以在条件满足时返回非NULL值,不满足时返回NULL,这样就能用COUNT统计出符合条件的记录数。
基础语法结构
通用的语法结构如下:
SELECT
分组字段,
-- 计算空值记录数:条件满足时返回1,否则返回NULL,COUNT会统计非NULL值
COUNT(CASE WHEN 目标字段 IS NULL THEN 1 END) AS null_count,
-- 计算总记录数
COUNT(*) AS total_count,
-- 计算空值比例,保留4位小数
ROUND(COUNT(CASE WHEN 目标字段 IS NULL THEN 1 END) * 1.0 / COUNT(*), 4) AS null_ratio
FROM 表名
GROUP BY 分组字段;
不同场景示例
示例1:按部门统计员工邮箱空值比例
假设有员工表employee,包含字段dept(部门)、name(姓名)、email(邮箱),需要统计每个部门的邮箱空值比例:
SELECT
dept,
COUNT(CASE WHEN email IS NULL THEN 1 END) AS null_email_count,
COUNT(*) AS total_emp_count,
ROUND(COUNT(CASE WHEN email IS NULL THEN 1 END) * 1.0 / COUNT(*), 4) AS email_null_ratio
FROM employee
GROUP BY dept;
示例2:统计空值和非空值的比例
如果需要同时统计空值和非空值的比例,可以扩展CASE WHEN的逻辑:
SELECT
分组字段,
-- 空值数量
COUNT(CASE WHEN 目标字段 IS NULL THEN 1 END) AS null_count,
-- 非空值数量
COUNT(CASE WHEN 目标字段 IS NOT NULL THEN 1 END) AS not_null_count,
-- 空值比例
ROUND(COUNT(CASE WHEN 目标字段 IS NULL THEN 1 END) * 1.0 / COUNT(*), 4) AS null_ratio,
-- 非空值比例
ROUND(COUNT(CASE WHEN 目标字段 IS NOT NULL THEN 1 END) * 1.0 / COUNT(*), 4) AS not_null_ratio
FROM 表名
GROUP BY 分组字段;
注意事项
- 除法运算时建议给分子乘以1.0,避免整数除法导致结果取整,比如MySQL中两个整数相除会返回整数,乘以1.0后会转为浮点数计算。
- 如果分组内总记录数为0,除法会出现除零错误,部分数据库会返回NULL,部分会报错,可以根据需要增加判断逻辑,比如用NULLIF函数处理分母为0的情况:
ROUND(COUNT(CASE WHEN 目标字段 IS NULL THEN 1 END) * 1.0 / NULLIF(COUNT(*), 0), 4)。 - 如果需要统计的是空字符串而非NULL值,需要把CASE WHEN中的
IS NULL改为= '',注意空字符串和NULL是不同的概念,COUNT不会忽略空字符串。
总结
通过COUNT和CASE WHEN的结合,可以灵活实现分组内的空值比例统计,这种方法兼容大部分关系型数据库,包括MySQL、PostgreSQL、SQL Server、Oracle等,只需要根据数据库特性调整ROUND等函数的用法即可。实际使用时注意区分NULL和空字符串的差异,避免统计结果不符合预期。