SQL Server如何按codes分组统计零、NULL、空格类缺失值占比
原SQL问题排查
原SQL无法得到正确结果,核心问题有4个:
- 总条数统计逻辑错误:
allcountCTE直接统计全表总记录数,未按codes维度分组,最后用笛卡尔积关联会导致所有编码拿到相同的全局总条数,分组统计完全失效 - 缺失值判断逻辑错误:原逻辑要求col1、col2同时为NULL/同时为空格才算缺失,不符合需求;需求是只要任意一个字段属于NULL、空/空格、0这类缺失值,该行就计入缺失统计
- 字段名混乱:语句中字段名前后不一致,
Codes/Code/ReadCode混用,子查询中也未查询ReadCode字段,执行时会直接报字段不存在错误 - 占比计算逻辑错误:直接用两个整数做除法,在绝大多数SQL引擎中会触发整数除法截断小数部分,比如2/3会得到0而非0.6667,最终百分比结果错误
正确实现代码
不需要写多CTE做笛卡尔积关联,单次分组聚合即可实现需求,兼容空值为多个空格的场景:
WITH base_mark AS ( SELECT codes, -- 逐行标记是否为缺失数据行 CASE WHEN (col1 IS NULL OR TRIM(col1) = '' OR TRIM(col1) = '0') OR (col2 IS NULL OR TRIM(col2) = '' OR TRIM(col2) = '0') THEN 1 ELSE 0 END AS is_missing FROM data1 ) SELECT codes, COUNT(*) AS total_count, SUM(is_missing) AS Missing_values, ROUND(100.0 * SUM(is_missing) / COUNT(*), 2) AS Missing_Percent FROM base_mark GROUP BY codes
逻辑说明
- 第一层CTE先做数据预处理:逐行判断是否为缺失行,用
TRIM()处理字段值,避免多个空格的场景被误判为非空值;只要col1、col2任意一个字段符合缺失规则,就将该行标记为1,否则标记为0 - 外层直接按
codes分组,统计每组的总行数、缺失行总数;计算占比时乘100.0触发浮点数除法,避免整数精度丢失,最后用ROUND()保留2位小数,和期望输出格式对齐 - 基于你提供的样例数据执行,返回结果和预期完全一致:code1总记录3条、缺失2条、占比66.67;code2总记录3条、缺失1条、占比33.33
内容的提问来源于stack exchange,提问作者Mikko
相关产品推荐
相关产品推荐

