一、题目来源
3322. 英超积分榜排名 III - 力扣(LeetCode)
二、数据表结构
表:SeasonStats
+------------------+---------+ | Column Name | Type | +------------------+---------+ | season_id | int | | team_id | int | | team_name | varchar | | matches_played | int | | wins | int | | draws | int | | losses | int | | goals_for | int | | goals_against | int | +------------------+---------+ (season_id, team_id) 是这张表的唯一主键。 这张表包含每个赛季中每支球队的赛季 id,队伍 id,队伍名,比赛场次,赢场,平局,输场,进球数 (goals_for),以及失球数 (goals_against)。
三、需求
编写一个解决方案来计算 每个赛季每支球队的积分,净胜球 和 排名。排名应确定如下:
- 球队首先按总分排名(从高到低)
- 如果积分持平,球队就会根据净胜球(从最高到最低)进行排名
- 如果净胜球也持平,则球队将按球队名称按字母顺序排名
积分如下计算:
- 赢局 有
3
点得分 - 平局 有
1
点得分 - 输局 有
0
点得分
净胜球计算如下:goals_for - goals_against
返回结果表以 season_id
升序 排序,然后以 rank
升序 排序,最后以 team_name
升序 排序。
四、示例数据
输入:
SeasonStats
表:
+------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+ | season_id | team_id | team_name | matches_played | wins | draws | losses | goals_for | goals_against | +------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+ | 2021 | 1 | Manchester City | 38 | 29 | 6 | 3 | 99 | 26 | | 2021 | 2 | Liverpool | 38 | 28 | 8 | 2 | 94 | 26 | | 2021 | 3 | Chelsea | 38 | 21 | 11 | 6 | 76 | 33 | | 2021 | 4 | Tottenham | 38 | 22 | 5 | 11 | 69 | 40 | | 2021 | 5 | Arsenal | 38 | 22 | 3 | 13 | 61 | 48 | | 2022 | 1 | Manchester City | 38 | 28 | 5 | 5 | 94 | 33 | | 2022 | 2 | Arsenal | 38 | 26 | 6 | 6 | 88 | 43 | | 2022 | 3 | Manchester United | 38 | 23 | 6 | 9 | 58 | 43 | | 2022 | 4 | Newcastle | 38 | 19 | 14 | 5 | 68 | 33 | | 2022 | 5 | Liverpool | 38 | 19 | 10 | 9 | 75 | 47 | +------------+---------+-------------------+----------------+------+-------+--------+-----------+---------------+
输出:
+------------+---------+-------------------+--------+-----------------+----------+ | season_id | team_id | team_name | points | goal_difference | position | +------------+---------+-------------------+--------+-----------------+----------+ | 2021 | 1 | Manchester City | 93 | 73 | 1 | | 2021 | 2 | Liverpool | 92 | 68 | 2 | | 2021 | 3 | Chelsea | 74 | 43 | 3 | | 2021 | 4 | Tottenham | 71 | 29 | 4 | | 2021 | 5 | Arsenal | 69 | 13 | 5 | | 2022 | 1 | Manchester City | 89 | 61 | 1 | | 2022 | 2 | Arsenal | 84 | 45 | 2 | | 2022 | 3 | Manchester United | 75 | 15 | 3 | | 2022 | 4 | Newcastle | 71 | 35 | 4 | | 2022 | 5 | Liverpool | 67 | 28 | 5 | +------------+---------+-------------------+--------+-----------------+----------+
解释:
- 对于 2021 赛季:
- 曼城有 93 积分 (29 * 3 + 6 * 1) 以及 73 (99 - 26) 个净胜球。
- 利物浦有 92 积分 (28 * 3 + 8 * 1) 以及 68 (94 - 26) 个净胜球。
- 切尔西有 74 积分 (21 * 3 + 11 * 1) 以及 43 (76 - 33) 个净胜球。
- 托特纳姆有 71 积分 (22 * 3 + 5 * 1) 以及 29 (69 - 40) 个净胜球。
- 阿森纳有 69 积分 (22 * 3 + 3 * 1) 以及 13 (61 - 48) 个净胜球。
- 对于 2022 赛季:
- 曼城有 89 积分 (28 * 3 + 5 * 1) 以及 61 (94 - 33) 个净胜球。
- 阿森纳有 84 积分 (26 * 3 + 6 * 1) 以及 45 (88 - 43) 个净胜球。
- 曼联有 75 积分 (23 * 3 + 6 * 1) 以及 15 (58 - 43) 个净胜球。
- 纽卡斯尔有 71 积分 (19 * 3 + 14 * 1) 以及 35 (68 - 33) 个净胜球。
- 利物浦有 67 积分 (19 * 3 + 10 * 1) 以及 28 (75 - 47) 个净胜球。
- 球队首先以积分排名,然后是净胜球,最后是球队名称。
- 输出以 season_id 升序排序,然后以排名升序排序,最后以 team_name 升序排序。
五、分析
1.文字分析
第一步:求出球队总分数points wins*3 + draws,然后求出净胜球goal_difference:goals_for - goals_against;
第二步:根据赛季分组使用rank()函数求出球队排名
2.图解
六、代码实现
with t1 AS (
SELECT
season_id,
team_id,
team_name,
wins * 3 + draws as points,
goals_for - goals_against as goal_difference
from seasonstats
)
SELECT
t1.*,
rank() OVER (PARTITION BY season_id ORDER BY t1.points desc,t1.goal_difference desc,t1.team_name) as position
from t1
ORDER BY season_id,position,team_name;
七、总结
本题需求为获取英超积分榜排名:
只需要求出球队总得分、净胜球数,然后根据赛季分组,根据总得分降序、净胜球数降序、队名升序进行排名即可;
因为积分相同的球队必须分配相同的排名,所以要选择使用 rank() 排名函数,结果是 存在并列排名但排名不连续的。