是否有查询以获取结果集

时间:2019-05-23 07:40:19

标签: mysql sql

我有一个表“ matches”,其中包含如下数据:

team1   team2   result_team_1   result_team_2
TEAM1   TEAM2   2               9
TEAM3   TEAM4   0               0

有没有一种方法(查询,视图等)来获取类似结果集

1 team2 9 2 3
2 team1 2 9 0
3 team3 0 0 1
4 team4 0 0 1

就像每种运动中已知的典型结果表一样。

2 个答案:

答案 0 :(得分:1)

此查询将在MySQL 5.x上运行。它使用MySQL变量模拟ROW_NUMBER函数。如果您使用的是MySQL 8+,我建议您进行第二次查询,因为MySQL 8中不推荐使用变量,并且在以后的版本中可能会删除它。

SELECT *,
       @rank := @rank + 1 AS position
FROM (
  SELECT team, 
         SUM(points) AS points, 
         SUM(goals_for) AS goals_for, 
         SUM(goals_against) AS goals_against
  FROM (
    SELECT team1 AS team,
           CASE WHEN m.result_team_1 > m.result_team_2 THEN 3
                WHEN m.result_team_1 = m.result_team_2 THEN 1
                ELSE 0 END AS points,
           m.result_team_1 AS goals_for,
           m.result_team_2 AS goals_against
    FROM matches m
    UNION ALL
    SELECT team2 AS team,
           CASE WHEN m.result_team_2 > m.result_team_1 THEN 3
                WHEN m.result_team_2 = m.result_team_1 THEN 1
                ELSE 0 END AS points,
           m.result_team_2 AS goals_for,
           m.result_team_1 AS goals_against
    FROM matches m
  ) r
  GROUP BY team
  ORDER BY points DESC, SUM(r.goals_for) - SUM(r.goals_against) DESC, goals_for DESC
) r
CROSS JOIN (SELECT @rank := 0) v
ORDER BY position

输出:

team    points  goals_for   goals_against   position
TEAM2   3       9           2               1
TEAM3   1       0           0               2
TEAM4   1       0           0               3
TEAM1   0       2           9               4

Demo on dbfiddle

此查询依赖于MySQL 8+,因为它使用CTE和ROW_NUMBER()函数(用于最终排名):

WITH teams AS (
  SELECT team1 AS team FROM matches
  UNION
  SELECT team2 FROM matches
),
results AS (
  SELECT t.team,
         SUM(CASE WHEN m.team1 = t.team AND m.result_team_1 > m.result_team_2 THEN 3
                  WHEN m.team2 = t.team AND m.result_team_2 > m.result_team_1 THEN 3
                  WHEN (m.team1 = t.team OR m.team2 = t.team) AND m.result_team_1 = m.result_team_2 THEN 1
                  ELSE 0 END) AS points,
         SUM(CASE WHEN m.team1 = t.team THEN m.result_team_1
                  ELSE m.result_team_2 END) AS goals_for,
         SUM(CASE WHEN m.team1 = t.team THEN m.result_team_2
                  ELSE m.result_team_1 END) AS goals_against
  FROM teams t
  JOIN matches m ON m.team1 = t.team OR m.team2 = t.team
  GROUP BY t.team)
SELECT t.team, r.points, r.goals_for, r.goals_against, 
       ROW_NUMBER() OVER(ORDER BY r.points DESC, r.goals_for - r.goals_against DESC, r.goals_for DESC) AS position
FROM teams t
JOIN results r ON r.team = t.team
ORDER BY position

输出:

team    points  goals_for   goals_against   position
TEAM2   3       9           2               1
TEAM3   1       0           0               2
TEAM4   1       0           0               3
TEAM1   0       2           9               4

Demo on dbfiddle

答案 1 :(得分:0)

您需要UNION ALL才能获得每个团队的结果。然后聚合。

select
  team,
  sum(made) as goals_made,
  sum(got) as goals_got,
  sum(case when made > got then 3 when made = got then 1 else 0 end) as points
from
(
  select team1 as team, result_team_1 as made, result_team_2 as got from matches
  union all
  select team2 as team, result_team_2 as made, result_team_1 as got from matches
) team_results
group by team
order by points;

用您认为合适的替换order by points。从MySQL 8开始,您可以使用ROW_NUMBER为位置编号。