首页 > 试题广场 >

刷题通过的题目排名

[编程题]刷题通过的题目排名
  • 热度指数:101478 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
在牛客刷题有一个通过题目个数的(passing_number)表,id是主键,简化如下:
id number
1
2
3
4
5
6
4
3
3
2
5
4
第1行表示id为1的用户通过了4个题目;

.....

第6行表示id为6的用户通过了4个题目;

请你根据上表,输出通过的题目的排名,通过题目个数相同的,排名相同,此时按照id升序排列,数据如下:

id number t_rank
5
1
6
2
3
4
5
4
4
3
3
2
1
2
2
3
3
4

id为5的用户通过了5个排名第1,

id为1和id为6的都通过了4个,并列第2

示例1

输入

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
方法一.首先要通过题目降序,id升序,那么sql应该为:
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;

方法二.使用mysql8.0(我强烈要求升级的mysql8.0,以便大家使用窗口函数)或者sqlite自带的dense_rank()函数,由于rank是mysql8.0的关键字,所以不能直接使用rank,要用" ` "号包裹,或者使用t_rank
SELECT
    id,number,
    dense_rank ( ) over ( ORDER BY number DESC ) `rank` 
FROM
    passing_number 
ORDER BY
    `rank`,
    id



编辑于 2020-11-05 14:57:39 回复(18)
使用窗口函数
    row_number() 是没有重复值的排序(即使两个记录相等也是不重复的),可以利用它来实现分页,如1,2,3,4
    dense_rank() 是连续排序,两个第二名仍然跟着第三名,如1,2,2,3
    rank()       是跳跃排序,两个第二名下来就是第四名,如1,2,2,4
select id,number,dense_rank() over(order by number desc) as `rank`
from passing_number
order by `rank`,id


编辑于 2022-02-17 10:47:12 回复(3)
两种解法:

1、两表自连接,通过查询比自己大的记录条数获取排名

先自连接,如 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;

2、对于支持窗口函数的,直接使用DENSE_RANK()进行排名

对于数据库支持分析函数的,可以使用分析函数将更简单,这里区别于 RANK(),详细用法请自行百度。注:mysql 8.0 开始才支持分析函数。
SELECT
	*,
	dense_rank ( ) over ( ORDER BY number DESC ) `rank` 
FROM
	passing_number 
ORDER BY
	`rank`,
	id

发表于 2020-09-13 01:29:56 回复(3)

两种解题方法

方法一:内置dense_rank函数

  • row_number对应唯一排序:1、2、3、4
  • dense_rank对应相同次序可重复,但不跳过下一个次序值:1、2、2、3
  • rank对应相同次序可重复,并且跳过下一个次序值:1、2、2、4
    select id, number, 
      dense_rank() over (order by number desc) t_rank
    from passing_number

    方法二:where子句

  • 关键是count中distinct的使用
    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
编辑于 2020-11-11 12:43:09 回复(0)
MySQL:

SELECT   id, 
         number,
         DENSE_RANK() OVER(ORDER BY number DESC) AS 'rank'
FROM    
         passing_number
ORDER BY
         rank, id;

编辑于 2020-09-02 23:11:53 回复(2)
SELECT
	*,
	dense_rank ( ) over ( ORDER BY number DESC ) `rank` 
FROM
	passing_number 
ORDER BY
	`rank`,
	id
MySQL的排名函数,引自https://www.cnblogs.com/shizhijie/p/9366247.html
发表于 2020-10-19 19:36:17 回复(0)
都8.0时代了,要技术进步- -

select
id,number,dense_rank() over(order by number Desc)
from passing_number
order by number desc


发表于 2022-05-16 10:09:34 回复(0)
# 法一: 常规写法
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;

发表于 2021-08-20 16:11:22 回复(1)
考点:mysql 8:dense_rank() 函数,number相同则排名相同,不会继续+1
select id, number, dense_rank() over (order by number desc) t_rank
from passing_number


发表于 2021-03-28 10:19:29 回复(0)
select *,
(select count(distinct number) from passing_number where number >= pn.number) as rank
from passing_number pn
order by pn.number desc,id 
发表于 2020-09-22 17:09:10 回复(0)
select id,number,dense_rank() over(order by number desc) as rank
from passing_number
order by rank,id
发表于 2020-09-08 17:11:07 回复(0)
select p1.id ,p1.number,count(distinct p2.number)as rank
from passing_number as p1 join passing_number as p2
on p1.number<=p2.number
group by p1.id (这里写group by p1.number 就会少掉重复的number排名)
order by rank ,p1.id
发表于 2020-08-17 22:56:40 回复(2)
select a.id, a.number, count(distinct b.number) as rank
from passing_number as a, passing_number as b
where a.number<=b.number
group by a.id
order by a.number desc,a.id asc

发表于 2020-08-14 16:50:14 回复(3)
# 请你根据上表,输出通过的题目的排名,通过题目个数相同的,排名相同,此时按照id升序排列,数据如下:

with dwd_data as (
select 
id,
number,
dense_rank()over(order by number desc) as t_rank
from passing_number
) 

select  
id,
number,
t_rank
from dwd_data
order by 3,1;

发表于 2023-09-13 11:00:29 回复(0)
SELECT 
    id,
    number,
    DENSE_RANK() OVER (ORDER BY number DESC) AS t_rank
FROM
    passing_number
ORDER BY
    t_rank 

发表于 2021-10-19 15:57:26 回复(1)
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, p1.id;
发表于 2020-09-04 14:49:54 回复(0)
set @i :=0;
set @q :=0;
set @p :=0;
set @j :=0;
select tt1.id,tt1.number,tt1.t_rank from (
select t1.id as id,
        t1.number as number,
        @i:=@j+1,
        @q :=t1.number,
        if(@q=@p,@i,@j := @j+1) as t_rank ,
        @p := @q
       from (select * from passing_number order by number desc) t1)tt1
这里运行不出来,但是我再我的mysql里可以

发表于 2024-03-29 17:12:34 回复(0)
select a.*,
(select count(distinct number) from passing_number where number>=a.number) t_rank 
from passing_number a
order by a.number desc;

发表于 2024-02-06 13:51:27 回复(0)
SELECT
    p1.id,p1.number,COUNT(DISTINCT p2.number) as t_rank
FROM
    passing_number p1,passing_number p2
WHERE
    p1.number<=p2.number
GROUP BY
    p1.id
ORDER BY
    t_rank ASC ,p1.id ASC 

使用自连接
发表于 2023-11-30 14:21:02 回复(0)
select
    id,
    number,
    dense_rank() over (
        order by
            number desc
    ) t_rank
from
    passing_number
order by
    t_rank,id

发表于 2023-11-24 14:34:19 回复(0)

问题信息

难度:
166条回答 3774浏览

热门推荐

通过挑战的用户

查看代码