Leetcode - Mysql ranking questions - 178. Rank Scores

以leetcode上这道题为例:


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    |
+-------+------+


1. row_number() in sql server:

row_number() over([partition by column1] order by column2 desc/asc) as Rank

该排序是从1开始,每行增加1,连续不断。

用Mysql如何实现?

  • Mysql可用user defined varible来解决:
SELECT s.Score, 
       @rownum := @rownum + 1 AS Rank
  FROM Scores s, 
       (SELECT @rownum := 0) r
order by s.Score desc;

得到table如下:

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 2    |
| 3.85  | 3    |
| 3.65  | 4    |
| 3.65  | 5    |
| 3.50  | 6    |
+-------+------+

2. rank() in sql server:

1

2

3

4

RANK() OVER (

    [PARTITION BY partition_expression, ... ]

    ORDER BY sort_expression [ASC | DESC], ...

)

  • 用MySql join实现:

from Scores s1, Scores s2
where s1.Id != s2.Id
and s1.Score <= s2.Score

得到如下的table:

id1score1id2score2
13.523.65
13.534
13.543.85
13.554
13.563.65
23.6534
23.6543.85
23.6554
23.6563.65
3454
43.8543.85
43.8534
43.8554
5434
63.6523.65
63.6534
63.6543.85
63.6554

可以看出,每个id1对应的score2数目就是其排名:

select s1.Score, count(s2.Id) as Rank
from Scores s1, Scores s2
where s1.Id != s2.Id
and s1.Score <= s2.Score
group by s1.Id
order by s1.Score desc

得到table如下:

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 3    |
| 3.65  | 4    |
| 3.65  | 4    |
| 3.50  | 6    |
+-------+------+

3. dense_rank() in sql server:

2

3

4

DENSE_RANK() OVER (

    [PARTITION BY partition_expression, ... ]

    ORDER BY sort_expression [ASC | DESC], ...

)

  • 同样可以用MySql的join来解决:

From Scores s1 inner join Scores s2 on s1.Score <= s2.Score

self join之后得到的table如下:

id1score1id2score2
13.513.5
13.523.65
13.534
13.543.85
13.554
13.563.65
23.6523.65
23.6534
23.6543.85
23.6554
23.6563.65
3434
3454
43.8543.85
43.8534
43.8554
5454
5434
63.6523.65
63.6534
63.6543.85
63.6554
63.6563.65

可以看出,这个时候每个id1对应的score2的unique数就是其排名:

Select s1.Score, count(Distinct s2.Score) as Rank
From Scores s1 inner join Scores s2
on s1.Score <= s2.Score
Group by s1.Id
Order by s1.Score desc;

得到table如下:

+-------+------+
| Score | Rank |
+-------+------+
| 4.00  | 1    |
| 4.00  | 1    |
| 3.85  | 2    |
| 3.65  | 3    |
| 3.65  | 3    |
| 3.50  | 4    |
+-------+------+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值