如何不使用UNION运算符用SQL基于赛事比分结果生成积分卡报表
赛事积分统计无UNION实现方案
完全可以不使用UNION运算符实现该需求,以下是两种可行的实现方式:
方案一:单行拆分法(支持MySQL 8.0+/PostgreSQL等主流新数据库)
核心逻辑是通过VALUES行构造器,把每场比赛的两条参赛记录一次性拆出来,仅扫描一次原表即可完成统计,性能优于原UNION方案:
SELECT team, COUNT(*) AS played, SUM(win) AS won, SUM(lose) AS lost, SUM(draw) AS draw FROM score CROSS JOIN ( VALUES -- 主队视角统计 (t1, IF(result=1,1,0), IF(result=2,1,0), IF(result=0,1,0)), -- 客队视角统计 (t2, IF(result=2,1,0), IF(result=1,1,0), IF(result=0,1,0)) ) AS stat(team, win, lose, draw) GROUP BY team ORDER BY team;
方案二:球队关联法(兼容低版本数据库,可完全无UNION)
如果有独立的球队维度表teams(存储所有参赛队伍名称),可以直接关联原表统计,全程不需要用到UNION:
SELECT t.team, COUNT(s.result) AS played, SUM( CASE WHEN (t.team = s.t1 AND s.result = 1) OR (t.team = s.t2 AND s.result = 2) THEN 1 ELSE 0 END ) AS won, SUM( CASE WHEN (t.team = s.t1 AND s.result = 2) OR (t.team = s.t2 AND s.result = 1) THEN 1 ELSE 0 END ) AS lost, SUM(IF(s.result=0,1,0)) AS draw FROM teams t LEFT JOIN score s ON t.team = s.t1 OR t.team = s.t2 GROUP BY t.team ORDER BY t.team;
如果没有单独的球队表,仅需要用UNION做一次球队名称去重,和原方案中用UNION拼接全量比赛数据的逻辑完全不同,性能消耗极低。
两种方案输出结果和原UNION实现完全一致,匹配需求给出的样例输出。
内容的提问来源于stack exchange,提问作者rahul_ramanan
相关产品推荐
相关产品推荐

