SQL实现LeetCode(178.分数排行)

[leetcode] 178.rank scores 分数排行

write a sql query to rank scores. if there is a tie between two scores, both should have the same ranking. note that after a tie, the next ranking number should be the next consecutive integer value. in other words, there should be no “holes” between ranks.

+—-+——-+
| id | score |
+—-+——-+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+—-+——-+

for example, given the above scores table, your query should generate the following report (order by highest score):

+——-+——+
| score | rank |
+——-+——+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+——-+——+

这道题给了我们一个分数表,让我们给分数排序,要求是相同的分数在相同的名次,下一个分数在相连的下一个名次,中间不能有空缺数字,这道题我是完全照着来写的,膜拜大神中…大神总结了四种方法,那么我们一个一个的来膜拜学习,首先看第一种解法,解题的思路是对于每一个分数,找出表中有多少个大于或等于该分数的不同的分数,然后按降序排列即可,参见代码如下:

解法一:

select score, 
(select count(distinct score) from scores where score >= s.score) rank 
from scores s order by score desc;

跟上面的解法思想相同,就是写法上略有不同:

解法二:

select score,
(select count(*) from (select distinct score s from scores) t where s >= score) rank
from scores order by score desc;

下面这种解法使用了内交,join是inner join的简写形式,自己和自己内交,条件是右表的分数大于等于左表,然后群组起来根据分数的降序排列,十分巧妙的解法:

解法三:

select s.score, count(distinct t.score) rank
from scores s join scores t on s.score <= t.score
group by s.id order by s.score desc;

下面这种解法跟上面三种的画风就不太一样了,这里用了两个变量,变量使用时其前面需要加@,这里的:= 是赋值的意思,如果前面有set关键字,则可以直接用=号来赋值,如果没有,则必须要使用:=来赋值,两个变量rank和pre,其中rank表示当前的排名,pre表示之前的分数,下面代码中的<>表示不等于,如果左右两边不相等,则返回true或1,若相等,则返回false或0。初始化rank为0,pre为-1,然后按降序排列分数,对于分数4来说,pre赋为4,和之前的pre值-1不同,所以rank要加1,那么分数4的rank就为1,下面一个分数还是4,那么pre赋值为4和之前的4相同,所以rank要加0,所以这个分数4的rank也是1,以此类推就可以计算出所有分数的rank了。

解法四:

select score,
@rank := @rank + (@pre <> (@pre := score)) rank
from scores, (select @rank := 0, @pre := -1) init 
order by score desc;

参考资料:

到此这篇关于sql实现leetcode(178.分数排行)的文章就介绍到这了,更多相关sql实现分数排行内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐