题目描述
(通过次数781 | 提交次数1,447,通过率53.97%)
表:TeamPoints +-------------+---------+ | Column Name | Type | +-------------+---------+ | team_id | int | | name | varchar | | points | int | +-------------+---------+ team_id 是这张表的主键。 这张表的每一行均包含了一支国家队的 ID,它所代表的国家,以及它在全球排名中的得分。没有两支队伍代表同一个国家。 表:PointsChange +---------------+------+ | Column Name | Type | +---------------+------+ | team_id | int | | points_change | int | +---------------+------+ team_id 是这张表的主键。 这张表的每一行均包含了一支国家队的 ID 以及它在世界排名中的得分的变化。 分数的变化分以下情况: - 0:代表分数没有改变 - 正数:代表分数增加 - 负数:代表分数降低 TeamPoints 表中出现的每一个 team_id 均会在这张表中出现。 国家队的全球排名是按 降序排列 所有队伍的得分后所得出的排名。如果两支队伍得分相同,我们将按其名称的 字典顺序 排列以打破平衡。 每支国家队的分数应根据其相应的 points_change 进行更新。 编写一条 SQL 查询来计算在分数更新后,每个队伍的全球排名的变化。 以 任意顺序 返回结果。 查询结果的格式如下例所示: 示例 1: 输入: TeamPoints 表: +---------+-------------+--------+ | team_id | name | points | +---------+-------------+--------+ | 3 | Algeria | 1431 | | 1 | Senegal | 2132 | | 2 | New Zealand | 1402 | | 4 | Croatia | 1817 | +---------+-------------+--------+ PointsChange 表: +---------+---------------+ | team_id | points_change | +---------+---------------+ | 3 | 399 | | 2 | 0 | | 4 | 13 | | 1 | -22 | +---------+---------------+ 输出: +---------+-------------+-----------+ | team_id | name | rank_diff | +---------+-------------+-----------+ | 1 | Senegal | 0 | | 4 | Croatia | -1 | | 3 | Algeria | 1 | | 2 | New Zealand | 0 | +---------+-------------+-----------+ 解释: 世界排名如下所示: +---------+-------------+--------+------+ | team_id | name | points | rank | +---------+-------------+--------+------+ | 1 | Senegal | 2132 | 1 | | 4 | Croatia | 1817 | 2 | | 3 | Algeria | 1431 | 3 | | 2 | New Zealand | 1402 | 4 | +---------+-------------+--------+------+ 在更新分数后,世界排名变为下表: +---------+-------------+--------+------+ | team_id | name | points | rank | +---------+-------------+--------+------+ | 1 | Senegal | 2110 | 1 | | 3 | Algeria | 1830 | 2 | | 4 | Croatia | 1830 | 3 | | 2 | New Zealand | 1402 | 4 | +---------+-------------+--------+------+ 由于在更新分数后,Algeria 和 Croatia 的得分相同,因此根据字典顺序对它们进行排序。 Senegal 丢失了22分但他们的排名没有改变。 Croatia 获得了13分但是他们的排名下降了1名。 Algeria 获得399分,排名上升了1名。 New Zealand 没有获得或丢失分数,他们的排名也没有发生变化。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/the-change-in-global-rankings
//测试数据 Create table If Not Exists TeamPoints (team_id int, name varchar(100), points int); Create table If Not Exists PointsChange (team_id int, points_change int); insert into TeamPoints (team_id, name, points) values ('3', 'Algeria', '1431'); insert into TeamPoints (team_id, name, points) values ('1', 'Senegal', '2132'); insert into TeamPoints (team_id, name, points) values ('2', 'New Zealand', '1402'); insert into TeamPoints (team_id, name, points) values ('4', 'Croatia', '1817'); insert into PointsChange (team_id, points_change) values ('3', '399'); insert into PointsChange (team_id, points_change) values ('2', '0'); insert into PointsChange (team_id, points_change) values ('4', '13'); insert into PointsChange (team_id, points_change) values ('1', '-22');
解题思路
TeamPoints表中保存了每个国家的当前分数。
根据当前分数,可以得出每个国家的当前排名。(使用开窗函数,如row_number)
PointsChange表保存了每个国家的分数变化。分数有可能增加,有可能减少,也可能不变。
当前分数+变化的分数=变化后的分数。那么,根据变化后的分数,可以得出每个国家变化后的排名。(仍然可以使用开窗函数)
题目要求:查询每个国家的排名变化。
如果某个国家当前排名第1,变化后排名第3,则排名变化为1-3=-2,表示下降了2名。
也就是说,根据上面计算出的当前排名减去变化后排名,即可得出排名的变化。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select a.team_id, a.name, cast(row_number() over(order by a.points desc,a.name) as signed) - cast(row_number() over(order by a.points + b.points_change desc,a.name)as signed) rank_diff from TeamPoints a inner join PointsChange b on a.team_id = b.team_id;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。