用mysql实现rank()排序

本文介绍了一种在MySQL中实现成绩排名的方法,即使面对相同成绩也能确保排名一致。通过使用自定义变量和CASE WHEN语句,文章详细展示了如何创建一个能够处理成绩排序并给出正确排名的SQL查询。

MySQL中不存在类似于SQL Server或Orcal中的rank()函数来得到排名。而在实际的工作中,常常需要将查询后排序得到的排名给记录下来。由于项目需要,不仅要对成绩进行排名,而且需要相同成绩的具有相同的排名。根据网上的提供的排名方法,进一步进行扩充,得到了下面的实现方式。

表:score,有三个字段,id,name,score
表中原始数据:
在这里插入图片描述
SQL代码:

select 
tmp.id,tmp.name,tmp.score,
-- 顺序一直在变大
@j:=@j+1 as j,
-- 只有在前后二次排序值不同时才会使用顺序号
@k:=(case when @pre_score=tmp.score then @k else @j end) as rank,
@pre_score:=tmp.score as pre_score
from 
(
-- 成绩排序
select * from score order by score desc
) tmp,
-- @k 表示最终的排名(相同值时序号相同) 
-- @j 表示顺序排名 
-- @pre_score上一次排序值
(select @k :=0,@j:=0, @pre_score:=0) sdcore

在这里插入图片描述

原文链接:http://www.cnblogs.com/bjwylpx/p/5345162.html

MySQL 中,`RANK()` 函数用于为结果集中的行分配排名。其基本使用方法如下: ### 简单排序 若要对整个结果集按照某个字段排序并分配排名,可使用如下语句: ```sql select id, name, rank() over(order by score desc) as r from students; ``` 此语句会依据 `score` 字段降序排列 `students` 表中的记录,同时为每条记录分配一个排名,排名存储在 `r` 列中。若有相同的 `score` 值,这些记录会得到相同的排名,且下一个排名会跳过相应数量的名次 [^1]。 ### 分区排序 若要按照某个字段分区进行排序,可使用 `PARTITION BY` 子句。例如按照 `name` 进行分区,根据分数进行排名,可使用如下语句: ```sql SELECT name, score, dense_rank() over(partition by name ORDER BY score desc) as 'Rank' FROM rank; ``` 这里,`PARTITION BY` 子句按 `name` 将结果集分成多个分区,接着 `ORDER BY` 子句按分数对每个分区内的结果集进行排名 [^3]。 ### 使用 MySQL 基本语法模拟 `RANK()` 函数排序 也可使用 MySQL 基本语法来模拟 `RANK()` 函数的排序效果: ```sql SELECT temp.pid,temp.name,temp.age, @j:=@j+1 AS number, @k:=(CASE WHEN @pre_age=temp.age THEN @k ELSE @j END) AS 'rank', @h:=(CASE WHEN @pre_age=temp.age THEN @h ELSE (CASE WHEN @h=0 THEN @j ELSE @h+1 END) END) AS 'rank2(本行可删除)', @pre_age:=temp.age AS pre_age FROM (SELECT * FROM players ORDER BY age ASC) temp, (SELECT @k:=0,@j:=0, @h:=0, @pre_age:=0) initNum; ``` 此语句通过变量和 `CASE` 语句模拟了 `RANK()` 函数的功能,依据 `age` 字段对 `players` 表中的记录进行排序并分配排名 [^2]。 ### 使用存储过程实现组内排序 还能通过创建存储过程实现组内排序的功能: ```sql -- 创建存储过程 DROP PROCEDURE IF EXISTS realize_rank_in_MySQL; DELIMITER ;; CREATE PROCEDURE realize_rank_in_MySQL() BEGIN DECLARE i int; SET i = 0; WHILE i < (select count(DISTINCT course) from student) DO SET @ROW =0; INSERT INTO student_rank SELECT *, (@ROW:=@ROW+1) AS rank FROM student WHERE course=(select DISTINCT course from student limit i,1) ORDER BY score DESC; set i = i + 1; END WHILE; END;; DELIMITER ; -- 执行存储过程 drop table if exists student_rank; create table student_rank like student; alter table student_rank add rank int; call realize_rank_in_MySQL; select * from student_rank; ``` 此存储过程会依据 `course` 字段对 `student` 表进行分组,然后在每个组内按照 `score` 降序排列并分配排名,最终将结果存储在 `student_rank` 表中 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值