题目描述:(来源:力扣数据库178)
编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。
例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):
我的解法:
SELECT
s3.Score,
s4.rank
FROM
Scores s3
LEFT JOIN ( #左连接
SELECT
s2.Score,
IF(#if判断,设置rank_num等级值
@rank_num < ( SELECT COUNT( DISTINCT Score ) FROM Scores ORDER BY Score DESC ),
@rank_num := @rank_num + 1,
NULL ) AS Rank
FROM(
SELECT DISTINCT s1.Score
FROM Scores s1, ( SELECT @rank_num := 0 ) t #初始化rank_num值
ORDER BY Score DESC ) s2
) s4
ON s3.Score = s4.Score
ORDER BY s4.rank;
步骤详解:
- 先对Scores表按照
Score
列进行去重,并降序排列;
#这里方便程序的理解,我使用了自定义变量;
#但是在leetcode中使用下面的的方式定义自定义变量会报错,
#在leetcode中可以使用上面我写的方法。
SET @rank_num:=0;#rank等级值
#去重后的表中记录数
SET @count:=(SELECT COUNT(DISTINCT Score) FROM Scores ORDER BY Score DESC);
SELECT s2.Score,IF(@rank_num< @count,@rank_num:=@rank_num+1,NULL) as rank
FROM(
SELECT DISTINCT s1.Score
FROM Scores s1
ORDER BY Score DESC
) s2 ;
运行结果:
- 将原来的Scores表和上面输出的临时表进行左连接,以两个表的
Score
字段作为连接条件,这样就可以知道原来的表中每一个Score的对应等级;
SET @rank_num:=0;
SET @count:=(SELECT COUNT(DISTINCT Score) FROM Scores ORDER BY Score DESC);
SELECT * #查询所有字段
FROM Scores s3
LEFT JOIN#左连接
(
SELECT s2.Score,IF(@rank_num< @count,@rank_num:=@rank_num+1,NULL) as rank
FROM(
SELECT DISTINCT s1.Score
FROM Scores s1
ORDER BY Score DESC
) s2
) s4
ON s3.Score=s4.Score;#连接条件:分数值相等
运行结果:
与前面第一步对应来看,这里的rank就是左连接后,原来的表所对应的rank值。
- 经过前面两步,已经得到了rank值,现在只需要将其排序,然后提取相应的字段输出即可。这里按照rank值升序排列。
SET @rank_num:=0;
SET @count:=(SELECT COUNT(DISTINCT Score) FROM Scores ORDER BY Score DESC);
SELECT s3.Score,s4.rank
FROM Scores s3
LEFT JOIN#左连接
(
SELECT s2.Score,IF(@rank_num< @count,@rank_num:=@rank_num+1,NULL) as Rank
FROM(
SELECT DISTINCT s1.Score
FROM Scores s1
ORDER BY Score DESC
) s2
) s4
ON s3.Score=s4.Score;#连接条件:分数值相等
ORDER BY s4.rank;#排序
运行结果:
在leetcode题解中看到一个比较简单的方法,比较巧妙。
主要思路:使用大于或等于当前这个分数的不重复的分数的数量作为排名。
select
a.Score as score ,
(
select count(distinct b.Score)
from Scores b
# 条件是这个分数不小于我,因为a、b表数据相同,所以排名值最小是1
where b.Score >=a.Score
) as rank # 统计b表符合条件的不重复的分数的数量作为排名
from Scores a
order by Score DESC; # 最后按分数(跟排名一样)降序排列
作者:zazalumonster
链接:https://leetcode-cn.com/problems/rank-scores/solution/mysqlbi-jiao-hao-li-jie-de-yi-chong-xie-fa-by-zaza/