SQL如何基于多参数分组计数生成占比列,分组函数报错如何解决?
错误原因
你遇到的报错核心是SQL不允许直接嵌套聚合函数,你写的SUM(Count(*))属于两层聚合函数直接嵌套,不符合SQL的执行逻辑:
- SQL执行时会先运行GROUP BY生成分组结果,再计算SELECT后的聚合函数,COUNT()是基于分组维度计算出的聚合结果,你无法在同层级的SELECT里直接对分组后的COUNT()再做SUM聚合
- 你写的子查询
( SELECT SUM(Count(*)) )没有指定数据源,也无法拿到全局的总计数
修复方案
方案1:使用窗口函数(支持MySQL 8.0+、PostgreSQL、SQL Server等主流新版本数据库)
直接用全局窗口计算所有分组的COUNT总和,写法最简单:
SELECT summoner_id, monster_1_id, monster_2_id, monster_3_id, monster_4_id, monster_5_id, monster_6_id, COUNT(*)/ SUM(COUNT(*)) OVER () AS Ratio FROM battledata.history GROUP BY summoner_id, monster_1_id, monster_2_id, monster_3_id, monster_4_id, monster_5_id, monster_6_id ;
这里SUM(COUNT(*)) OVER ()会计算所有分组的COUNT()之和,也就是你需要的总获胜次数,直接和当前分组的COUNT()相除就能得到占比。
方案2:兼容老版本数据库的写法
如果你的数据库不支持窗口函数,可以把子查询改成直接统计全表总条数:
SELECT summoner_id, monster_1_id, monster_2_id, monster_3_id, monster_4_id, monster_5_id, monster_6_id, COUNT(*)/ (SELECT COUNT(*) FROM battledata.history) AS Ratio FROM battledata.history GROUP BY summoner_id, monster_1_id, monster_2_id, monster_3_id, monster_4_id, monster_5_id, monster_6_id ;
因为你分组统计的COUNT()总和刚好等于全表的总行数,所以直接查询全表COUNT()就能得到总获胜次数。
内容的提问来源于stack exchange,提问作者Sharan Balani
相关产品推荐
相关产品推荐

