如何使用SQL对相似SELECT查询结果进行聚合求和?
问题原因
你当前的UNION ALL写法仅会将两个子查询的结果集纵向拼接,不会对拼接后的结果做二次聚合,和你预期的按COLUMN_01合并求和的逻辑不符:
- 两个子查询分别独立按
COLUMN_01分组计算,会各自输出一组COLUMN_01值,拼接后同一个COLUMN_01会对应两行独立记录 - 第二个子查询的计算列别名是
SUM_02,拼接后列名会沿用第一个子查询的SUM_01,和你预期的单值列结构不匹配 - 原语句存在语法隐患:字符串值
ALFA/BETA未加单引号,table是SQL标准保留字,未转义的情况下多数数据库会抛出语法错误。
正确实现方案
方案1:条件聚合(性能最优,首推)
无需拼接多个结果集,仅通过一次表扫描即可完成计算,用CASE WHEN针对不同COLUMN_05值匹配对应的计算系数,直接聚合得到结果:
SELECT COLUMN_01, SUM( CASE WHEN COLUMN_05 = 'ALFA' THEN COLUMN_02 * 0.05 WHEN COLUMN_05 = 'BETA' THEN COLUMN_02 * 0.45 ELSE 0 END ) AS SUM_01 FROM `table` WHERE COLUMN_03 = 1 AND COLUMN_04 = 2 AND COLUMN_05 IN ('ALFA', 'BETA') GROUP BY COLUMN_01;
方案2:UNION ALL结果二次聚合
如果你需要保留多段独立SELECT的写法,可以在UNION ALL的结果外层套一层查询,做二次分组求和:
SELECT COLUMN_01, SUM(calc_val) AS SUM_01 FROM ( SELECT COLUMN_01, SUM(COLUMN_02) * 0.05 AS calc_val FROM `table` WHERE COLUMN_03 = 1 AND COLUMN_04 = 2 AND COLUMN_05 = 'ALFA' GROUP BY COLUMN_01 UNION ALL SELECT COLUMN_01, SUM(COLUMN_02) * 0.45 AS calc_val FROM `table` WHERE COLUMN_03 = 1 AND COLUMN_04 = 2 AND COLUMN_05 = 'BETA' GROUP BY COLUMN_01 ) t GROUP BY COLUMN_01;
扩展性与性能说明
- 条件聚合方案扩展性最好:后续新增同类计算规则时,只需要在
CASE WHEN块中追加对应分支、在IN条件中追加对应的过滤值即可,全程仅做一次表扫描,哪怕扩展到十数种规则也不会出现性能大幅下降的问题。 - 多分支
UNION ALL+外层聚合的方案性能随分支数线性变化:每新增一个UNION分支就会新增一次对原表的独立查询,当分支数量增多、单表数据量较大时,查询耗时会明显上涨,不适合分支过多的场景。 - 禁止用
UNION替代UNION ALL:UNION会对拼接后的全量结果做去重操作,会额外产生排序、哈希去重的计算开销,性能远低于UNION ALL。
内容的提问来源于stack exchange,提问作者Aloysia de Argenteuil
相关产品推荐
相关产品推荐

