SQL Server统计各州配送方式分布占比及代码优化方案
问题根因
原有按州统计的代码中,占比计算的分母固定取全表总记录数,没有按state维度匹配对应州的总记录数,最终计算结果是「某州某配送方式记录占全表总记录的比例」,而非「某配送方式在所属州内的分布占比」,因此单个州下所有配送方式的占比总和远低于100%,不符合需求。
修正后可直接运行的代码
适配SQL Server语法(原代码使用方括号别名,符合SQL Server书写规范),使用窗口函数实现分区计数,无需额外关联子查询:
SELECT state, ship_mode, ROUND(CAST(COUNT(ship_mode) * 100 AS FLOAT) / SUM(COUNT(*)) OVER(PARTITION BY state), 2) AS Percentage FROM sales_data_clean GROUP BY state, ship_mode ORDER BY state, ship_mode
代码逻辑说明:SUM(COUNT(*)) OVER(PARTITION BY state)会在state+ship_mode维度分组聚合完成后,按州分区计算当前州的所有记录总数,自动作为该州下所有配送方式占比计算的分母,保证单个州下所有配送方式占比总和为100%。
百分比计算代码行优化方案
- 替换固定全表计数子查询为窗口函数计数:原写法中全表计数的嵌套子查询会额外扫描全表计算总数,性能损耗高;换成窗口分区计数后,直接基于分组聚合结果计算分区总数,性能更高,且适配性强——如果后续要切换统计维度(比如按城市、按品类统计占比),只需要修改
PARTITION BY后的字段即可,计算全表占比时直接去掉PARTITION BY state写成SUM(COUNT(*)) OVER()就能拿到全表总记录数,无需再写嵌套子查询。 - 简化浮点类型转换逻辑:原写法中多次使用
CAST做类型转换,实际可以直接将整数100写为浮点数100.0,SQL Server会在运算时自动将整数类型的计数结果提升为浮点类型,避免整数除法截断问题,写法更简洁。 - 增加除零异常兼容:给分母增加
NULLIF判断,当分区总记录数为0时返回NULL而非直接抛出除零错误,提升查询鲁棒性。
优化后的最终百分比计算行写法:
ROUND(COUNT(ship_mode) * 100.0 / NULLIF(SUM(COUNT(*)) OVER(PARTITION BY state), 0), 2) AS Percentage
内容的提问来源于stack exchange,提问作者tajimari
相关产品推荐
相关产品推荐

