如何高效执行含GROUP BY的两张表查询UNION并简化重复代码
SQL重复逻辑优化方案
首先需要先指出你给出的示例查询存在逻辑隐患:第一段select state, count(*) from table1缺少GROUP BY state子句,在PostgreSQL、Oracle以及开启ONLY_FULL_GROUP_BY模式的MySQL中会直接报语法错误;即使在非严格模式下能执行,返回的state值是随机取自表中某行,count(*)是table1的全表总行数,和第二段按state分组计数的逻辑不匹配,大概率是书写笔误。
如果你的实际需求是统计两个表中各个state对应的总记录数,可以通过「先合并原始数据、再统一聚合」的方式完全消除重复代码,执行效率也比分别聚合再UNION更高:
SELECT state, COUNT(*) FROM ( SELECT state FROM table1 UNION ALL SELECT state FROM table2 ) AS combined_table GROUP BY state
写法说明
- 内层合并数据用
UNION ALL而非UNION:UNION会在合并阶段做全量数据去重,带来不必要的性能开销,外层的GROUP BY本身就会按state维度归并计算,不需要提前去重。 - 这种写法只需要写一次聚合逻辑,后续如果要调整统计规则(比如增加
WHERE筛选条件、更换聚合字段、新增统计维度),只需要修改一处即可,维护成本更低。
如果你确实需要保留原查询的特殊逻辑(即table1返回全表计数的单行结果、table2按state分组计数,再对两个结果集做去重合并),可以通过CTE封装公共聚合逻辑减少重复,但这种业务场景非常少见:
WITH agg_result AS ( SELECT state, COUNT(*) AS cnt FROM table2 GROUP BY state ) SELECT state, cnt FROM agg_result UNION SELECT state, COUNT(*) FROM table1
注:该写法中table1无GROUP BY的逻辑依然存在之前提到的语法兼容和结果不确定问题,除非明确业务需要,否则不建议使用。
内容的提问来源于stack exchange,提问作者Shashidhar R
相关产品推荐
相关产品推荐

