如何在SQL GROUP BY分组后计算单组值占指定分组总和的占比
实现方案
方案1:窗口函数实现(兼容支持窗口函数的主流数据库:MySQL 8.0+、PostgreSQL、Oracle等)
你需要计算的三个分组总和是固定范围的全局值,可以直接用SUM() OVER()窗口函数计算,不需要二次查表:
SELECT Name, SUM(Val) AS group_sum, SUM(Val) / SUM(SUM(Val)) OVER() AS ratio FROM Synthese WHERE Name IN ('Test1', 'Test2', 'Test3') GROUP BY Name;
如果你的Val字段是带$前缀的字符串类型,需要先转成数值再计算,以MySQL为例转数值写法:
SELECT Name, SUM(REPLACE(Val, '$', '') + 0) AS group_sum, SUM(REPLACE(Val, '$', '') + 0) / SUM(SUM(REPLACE(Val, '$', '') + 0)) OVER() AS ratio FROM Synthese WHERE Name IN ('Test1', 'Test2', 'Test3') GROUP BY Name;
方案2:子查询实现(兼容所有数据库版本)
如果数据库不支持窗口函数,可以单独写子查询先算出三个分组的总金额,再做除法运算:
SELECT t.Name, t.group_sum, t.group_sum / total.total_sum AS ratio FROM ( SELECT Name, SUM(Val) AS group_sum FROM Synthese WHERE Name IN ('Test1', 'Test2', 'Test3') GROUP BY Name ) t CROSS JOIN ( SELECT SUM(Val) AS total_sum FROM Synthese WHERE Name IN ('Test1', 'Test2', 'Test3') ) total;
Val为带$字符串的场景,把对应位置的SUM(Val)替换为SUM(REPLACE(Val, '$', '') + 0)即可生效。
输出说明
根据你给出的测试数据,最终计算得到的ratio列结果分别为≈0.1667、≈0.3333、≈0.5,完全匹配你给出的计算逻辑。
内容的提问来源于stack exchange,提问作者TourEiffel
相关产品推荐
相关产品推荐

