id | number |
1 | 4 |
2 | 3 |
3 | 3 |
4 | 2 |
5 | 5 |
6 | 4 |
.....
第6行表示id为6的用户通过了4个题目;
请你根据上表,输出通过的题目的排名,通过题目个数相同的,排名相同,此时按照id升序排列,数据如下:
id | number | t_rank |
5 | 5 | 1 |
1 | 4 | 2 |
6 | 4 | 2 |
2 | 3 | 3 |
3 | 3 | 3 |
4 | 2 | 4 |
id为5的用户通过了5个排名第1,id为1和id为6的都通过了4个,并列第2。
id | number |
1 | 4 |
2 | 3 |
3 | 3 |
4 | 2 |
5 | 5 |
6 | 4 |
id | number | t_rank |
5 | 5 | 1 |
1 | 4 | 2 |
6 | 4 | 2 |
2 | 3 | 3 |
3 | 3 | 3 |
4 | 2 | 4 |
drop table if exists passing_number; CREATE TABLE `passing_number` ( `id` int(4) NOT NULL, `number` int(4) NOT NULL, PRIMARY KEY (`id`)); INSERT INTO passing_number VALUES (1,4), (2,3), (3,3), (4,2), (6,4), (5,5);
5|5|1 1|4|2 6|4|2 2|3|3 3|3|3 4|2|4
select a.id,a.number from passing_number a order by a.number desc, a.id asc;要得到通过题目的排名,比如你通过了8分,,你同学a也通过了8分,找到大于等于你的成绩,一个9分,一个8分,一个8分,去重复,就一个9,一个8,count一下总数,第2名,如果有三个同学通过了7个呢,同理,9,8,8,7,7,7 后面比这个少的,已经死在了筛选条件,去重,9,8,7,count=3,所以sql为:
select count(distinct b.number) from passing_number b where b.number>=X联立为:
select a.id,a.number, (select count(distinct b.number) from passing_number b where b.number>=a.number ) from passing_number a order by a.number desc, a.id asc;
SELECT id,number, dense_rank ( ) over ( ORDER BY number DESC ) `rank` FROM passing_number ORDER BY `rank`, id
select id,number,dense_rank() over(order by number desc) as `rank` from passing_number order by `rank`,id
先自连接,如 id 为5的记录,通过连接可以得出比自己大的只有本身,因此COUNT的结果为1,加 DISTINCT 是在 number 相同的情况下让排名相同。
SELECT p1.id, p1.number, count( DISTINCT p2.number ) rank FROM passing_number p1, passing_number p2 WHERE p1.number <= p2.number GROUP BY p1.id ORDER BY `rank` ASC, p1.id ASC;
对于数据库支持分析函数的,可以使用分析函数将更简单,这里区别于 RANK(),详细用法请自行百度。注:mysql 8.0 开始才支持分析函数。
SELECT *, dense_rank ( ) over ( ORDER BY number DESC ) `rank` FROM passing_number ORDER BY `rank`, id
两种解题方法
select id, number, dense_rank() over (order by number desc) t_rank from passing_number
select a.id, a.number, count(distinct b.number) as t_rank from passing_number as a inner join passing_number as b on a.number <= b.number group by a.id, a.number order by t_rank asc
SELECT *, dense_rank ( ) over ( ORDER BY number DESC ) `rank` FROM passing_number ORDER BY `rank`, idMySQL的排名函数,引自https://www.cnblogs.com/shizhijie/p/9366247.html
# 法一: 常规写法 SELECT p.id, p.number, tmp.t_rank FROM passing_number p JOIN( # 确定每个id的排名 SELECT pn1.id, COUNT(DISTINCT pn2.number) AS t_rank FROM passing_number pn1 JOIN passing_number pn2 ON pn1.number <= pn2.number GROUP BY pn1.id ) tmp ON p.id = tmp.id ORDER BY p.number DESC, p.id ASC;
# 法二: 窗口函数 SELECT id, number, dense_rank() OVER(ORDER BY number DESC) FROM passing_number;
select id, number, dense_rank() over (order by number desc) t_rank from passing_number
select id, number, dense_rank() over(order by number desc) as t_rank from passing_number order by t_rank