SQL聚合函数SUM输出异常:人均车祸率计算结果错误排查求助
问题分析与解决方案
核心问题
你的查询结果错误的根本原因有两个:
- 人口字段格式错误:
population_table中的Population是带千分位逗号的字符串(如3,032,870),而非数值类型。SQL在执行除法时,会将这类字符串强制转换为数值,但转换过程中会截断逗号后的内容,只保留3,最终导致SUM(c.Crashes)/3得到数万的错误结果。 - 不必要的
ANY_VALUE使用:由于population_table中每个年份对应唯一的人口数,在GROUP BY p.Year的前提下,直接引用p.Population不会触发ONLY_FULL_GROUP_BY报错(主流数据库如MySQL 8.0+、PostgreSQL、SQL Server均支持这种分组逻辑)。
修正后的SQL查询
以MySQL为例,修正后的语句如下:
SELECT p.Year, (SUM(c.Crashes) / CAST(REPLACE(p.Population, ',', '') AS UNSIGNED)) AS `Crashes per Capita` FROM crash_table c INNER JOIN date_table d ON c.Date = d.Date INNER JOIN population_table p ON d.Year = p.Year WHERE p.Year != 2024 GROUP BY p.Year, p.Population;
如果你的数据库是PostgreSQL,可将数值转换部分替换为:
CAST(REPLACE(p.Population, ',', '') AS numeric)
如果是SQL Server:
CAST(REPLACE(p.Population, ',', '') AS INT)
关键修正点说明
- 清理并转换人口字段:通过
REPLACE(p.Population, ',', '')去除千分位逗号,再用CAST转换为数值类型,确保除法是正确的数值运算。 - 优化分组逻辑:在
GROUP BY中加入p.Population,既符合ONLY_FULL_GROUP_BY的要求,也让分组逻辑更清晰(每个年份对应唯一人口数,分组后不会改变结果)。
内容的提问来源于stack exchange,提问作者Nathan Stone
相关产品推荐
相关产品推荐

