178. 分数排名
题目要求
查询并对分数进行排序。排名按以下规则计算:
分数应按从高到低排列。
如果两个分数相等,那么两个分数的排名应该相同。
在排名相同的分数后,排名数应该是下一个连续的整数。换句话说,排名之间不应该有空缺的数字。
按 score 降序返回结果表。
查询结果格式如下所示。
示例 1:
输入:
Scores 表:
+----+-------+
| id | score |
+----+-------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+----+-------+
输出:
+-------+------+
| score | rank |
+-------+------+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+-------+------+
思路
题目要求就是让我们将原表内的score字段按照从大到小倒序排列,同时生成新字段为rank,表示每个记录的排名。要求排名【如果两个分数相等,那么两个分数的排名应该相同。在排名相同的分数后,排名数应该是下一个连续的整数。】
这个看起来还是挺复杂的,我们一点一点来看。
先将数据按照score字段倒序排列。代码如下:
SELECT
S.score,
FROM
Scores S
ORDER BY
S.score DESC
;
那么如何获取每一行的score字段值在整个数据表内的排名呢?
其实在这里,我们有mysql的DENSE_RANK() 窗口函数来实现这个功能。
DENSE_RANK()
这个函数功能:返回当前行在其分区中的排名,没有间隙。对等项被视为并列并获得相同的排名。此函数为对等组分配连续的排名;结果是大于一的组不产生不连续的排名号码。【恰好和要求一致】
一般用法
下面是DENSE_RANK()函数的一般语法:
DENSE_RANK() OVER (
ORDER BY column1 [ASC|DESC], column2 [ASC|DESC], ...
) AS dense_rank
我们使用一个示例来实际操作一下
示例
假设我们有一个名为students的表,其中包含学生姓名和他们的年龄。我们想要计算每个学生的年龄排名,可以使用DENSE_RANK()函数
+--------------+-----+
| student_name | age |
+--------------+-----+
| John | 20 |
| Alice | 22 |
| Bob | 20 |
| Mary | 21 |
| David | 21 |
+--------------+-----+
执行代码是:
SELECT
student_name,
age,
DENSE_RANK() OVER (ORDER BY age) AS age_dense_rank
FROM
students;
查询的结果将是:
+--------------+-----+--------------+
| student_name | age | age_dense_rank |
+--------------+-----+--------------+
| John | 20 | 1 |
| Bob | 20 | 1 |
| Mary | 21 | 2 |
| David | 21 | 2 |
| Alice | 22 | 3 |
+--------------+-----+--------------+
在这个示例中,年龄为20岁的学生排名为1,年龄为21岁的学生排名为2,年龄为22岁的学生排名为3。密集排名没有间隔,即使有相同的年龄也不会影响排名的连续性。
解法1
看完上面的示例,我们使用类似的代码来完成当前这道题。
代码修改后如下:
SELECT
S.score,
DENSE_RANK() OVER (
ORDER BY
S.score DESC
) AS 'rank'
FROM
Scores S;
执行成功!!