mysql SQL足球比赛练习-添加列、详细信息和改进的排名

eimct9ow  于 2023-03-11  发布在  Mysql
关注(0)|答案(3)|浏览(119)

我最近开始练习SQL,之前使用MySQL只是为了管理网站数据库,但没有实际的SQL查询构造经验。以前有人问过这个练习的变体,但我想扩展以前解决方案的范围。这是一个足球(足球)得分练习,构建一个小联盟中不同游戏的汇总结果表。

TL;DR我设法得到了部分解决方案,但希望在最终表中再添加3列,并改进计算最终排名的方式。

我创建了一个包含4个团队的表格,并为每个团队分配了一个ID:

CREATE TABLE Teams AS
  SELECT 100 AS TEAM_ID, 'PUMP' AS TEAM UNION ALL
  SELECT 200, 'UP' UNION ALL
  SELECT 300, 'THE' UNION ALL
  SELECT 400, 'JAM';

其输出为:

SELECT * FROM Teams

还有一张table:
| 团队编号|团队|
| - ------|- ------|
| 一百|泵|
| 二百|向上|
| 三百|该|
| 四百|果酱|
然后,我创建了第二个表,按游戏显示比赛分数:

CREATE TABLE Matches AS
SELECT 1 AS MATCH_ID, 100 AS HomeTeam, 200 AS AwayTeam, 2 AS HomeScore, 0 AS AwayScore UNION ALL 
SELECT 2, 300, 400, 1, 1 UNION ALL
SELECT 3, 400, 100, 0, 1 UNION ALL
SELECT 4, 300, 200, 2, 3 UNION ALL
SELECT 5, 200, 400, 0, 0 UNION ALL
SELECT 6, 300, 100, 1, 0;

接收:
| 匹配ID|家庭团队|出发队|家庭评分|离开分数|
| - ------|- ------|- ------|- ------|- ------|
| 1个|一百|二百|第二章|无|
| 第二章|三百|四百|1个|1个|
| 三个|四百|一百|无|1个|
| 四个|三百|二百|第二章|三个|
| 五个|二百|四百|无|无|
| 六个|三百|一百|1个|无|
我能够创建一个总得分表,显示每个球队的总联赛积分,使用以下积分规则:

  • 一队赢了得3分,
  • 平局得1分,
  • 队伍输了得0分
WITH cteHomePoints AS (SELECT HomeTeam AS Team,
                              CASE
                                WHEN HomeScore > AwayScore THEN 3
                                WHEN HomeScore = AwayScore THEN 1
                                ELSE 0
                              END AS Points
                         FROM Matches),
     cteAwayPoints AS (SELECT AwayTeam AS Team,
                               CASE
                                 WHEN AwayScore > HomeScore THEN 3
                                 WHEN AwayScore = HomeScore THEN 1
                                 ELSE 0
                               END AS Points
                          FROM Matches),
     cteAllPoints AS (SELECT Team, Points FROM cteHomePoints
                      UNION ALL
                      SELECT Team, Points FROM cteAwayPoints)
SELECT t.TEAM_ID, t.TEAM, COALESCE(SUM(ap.POINTS), 0) AS TOTAL_POINTS
  FROM Teams t
  LEFT OUTER JOIN cteAllPoints ap
    ON ap.TEAM = t.TEAM_ID
  GROUP BY  t.TEAM_ID, t.TEAM
  ORDER BY COALESCE(SUM(POINTS), 0) DESC, t.TEAM_ID

由此得出下表:
| 团队编号|团队|总计_点|
| - ------|- ------|- ------|
| 一百|泵|六个|
| 二百|向上|四个|
| 三百|该|四个|
| 四百|果酱|第二章|

但是,有两件事我想完成:

1.我想在最终表格中再添加3列,以显示每个团队:

  • 目标得分
  • 收到的目标
  • 差异(评分和接收之间)

1.球队位置由分数决定,如果平局,位置由更好的“净胜球”决定,即得分减去收到的进球。这会影响最终排名(第二名和第三名将交换位置)。
我尝试了几种不同的方法,比如添加

cteHomeScore AS (SELECT HomeTeam AS Team,
                             END AS Scored
                         FROM Matches),
     cteAwayScore AS (SELECT AwayTeam AS Team,
                             END AS Received
                         FROM Matches),                               
     cteAllScored AS (SELECT Team, Scored FROM cteHomeScore
                      UNION ALL
                      SELECT Team, Received FROM cteAwayScore),

但我好像破解不了。
任何帮助都将不胜感激:)

sg3maiej

sg3maiej1#

这是一种不同的方法:

SELECT T.TEAM_ID, T.TEAM, 
        SUM(points) AS Points, 
        SUM(HomeScore) AS 'Goals Scored', 
        SUM(AwayScore) AS 'Goals Received',
        SUM(HomeScore-AwayScore) 'GoalDiff'
 FROM 
Teams T 
LEFT JOIN
(SELECT HomeTeam AS Team, HomeScore, AwayScore,
       CASE WHEN HomeScore > AwayScore THEN 3
            WHEN HomeScore = AwayScore THEN 1
            ELSE 0
            END AS Points
FROM Matches UNION ALL
SELECT AwayTeam,  AwayScore, HomeScore,
       CASE WHEN AwayScore > HomeScore THEN 3
            WHEN AwayScore = HomeScore THEN 1
            ELSE 0
            END
FROM Matches) mm
ON T.TEAM_ID=mm.team
GROUP BY T.TEAM_ID, T.TEAM
ORDER BY Points DESC, GoalDiff DESC

**更新:**我已经将HomeScoreAwayScore的顺序从SELECT部分的HomeScore, AwayScore切换到AwayScore, HomeScore,并将UNION ALL子查询中第二个查询的CASE表达式的HomeScore > AwayScore切换到AwayScore > HomeScore,这是@JanezKuhar的一个非常好的观察结果。

This is the extended fiddle inclusive of the additional data suggested

idfiyjo8

idfiyjo82#

考虑包含所需聚合和条件聚合的自联接(而不是UNION)。如注解所示,根据需要调整计算:

WITH aggHome AS (
     SELECT HomeTeam AS Team
          , SUM(CASE
                  WHEN HomeScore > AwayScore THEN 3
                  WHEN HomeScore = AwayScore THEN 1
                  ELSE 0
                END) AS HomeSumPoints
          , SUM(HomeScore) As HomeSumScores
          , SUM(AwayScore) As HomeSumReceived
     FROM Matches
     GROUP BY HomeTeam
),
    aggAway AS (
     SELECT AwayTeam AS Team
          , SUM(CASE
                  WHEN AwayScore > HomeScore THEN 3
                  WHEN AwayScore = HomeScore THEN 1
                  ELSE 0
                END) AS AwaySumPoints
          , SUM(AwayScore) As AwaySumScores
          , SUM(HomeScore) As AwaySumReceived
     FROM Matches
     GROUP BY AwayTeam
)

SELECT h.Team
     , HomeSumPoints + AwaySumPoints As TotalPoints
     , HomeSumScores + AwaySumScores As GoalsScores
     , HomeSumReceived + AwaySumReceived As GoalsReceived
     , (HomeSumScores + AwaySumScores) - 
       (HomeSumReceived + AwaySumReceived) As Difference
FROM aggHome h
LEFT JOIN aggAway a
  ON h.Team = a.Team

注意:如果一些球队 * 只 * 打主场游戏或 * 只 * 打客场比赛,请用MySQL的INNER JOIN替换SQL的FULL OUTER JOIN

6vl6ewon

6vl6ewon3#

这是代码得分为100%的SQL

SELECT 
a.team_id,
a.team_name,
(
coalesce ((SELECT 

sum(case when guest_goals > host_goals then 3
     when guest_goals = host_goals then 1
     else 0 end) as guest_points      
from matches where guest_team=a.team_id group by guest_team),0) +
coalesce ((SELECT 
sum(case when host_goals > guest_goals then 3
     when host_goals = guest_goals then 1
     else 0 end) as host_points      
from matches where host_team=a.team_id group by host_team),0) ) as num_points

from teams  a
order by num_points desc,a.team_id

相关问题