MySQL中多种排名实现
一、数据库表结构以及数据
CREATE TABLE `forlan_score` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`student_name` varchar(255) DEFAULT NULL COMMENT '学生名称',
`score` int(20) DEFAULT '-1' COMMENT '分数',
`course_name` varchar(255) DEFAULT NULL COMMENT '课程',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='学生成绩表';
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (1, '小明', 70, '数学');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (2, '小红', 65, '英语');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (3, '小林', 100, '数学');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (4, '小黄', 100, '语文');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (5, '小东', 80, '语文');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (6, '小美', 90, '英语');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (7, '小伟', 88, '英语');
INSERT INTO `test`.`forlan_score` (`id`, `student_name`, `score`, `course_name`) VALUES (8, '小小', 100, '数学');
二、实现排名(不分组)
1、不重复,连续
1.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量(外部sql)
SET @cur_rank := 0;
SELECT
student_name,
score,
@cur_rank := @cur_rank + 1 AS ranking
FROM
forlan_score
ORDER BY
score DESC;
- 使用自定义变量(内部sql)(推荐)
SELECT
fs.student_name,
fs.score,
( @cur_rank := @cur_rank + 1 ) AS ranking
FROM
forlan_score fs,
( SELECT @cur_rank := 0 ) r
ORDER BY
score DESC;
2)mysql8实现
ROW_NUMBER()
SELECT
student_name,
score,
ROW_NUMBER() OVER ( ORDER BY score DESC ) AS ranking
FROM
forlan_score;
1.2、效果
+--------------+-------+---------+
| student_name | score | ranking |
+--------------+-------+---------+
| 小林 | 100 | 1 |
| 小黄 | 100 | 2 |
| 小小 | 100 | 3 |
| 小美 | 90 | 4 |
| 小伟 | 88 | 5 |
| 小东 | 80 | 6 |
| 小明 | 70 | 7 |
| 小红 | 65 | 8 |
+--------------+-------+---------+
2、并列排名,连续
2.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量 + IF
SELECT
fs.student_name,
fs.score,
IF( @pre_score = fs.score, @cur_rank, @cur_rank := @cur_rank + 1 ) AS ranking,
@pre_score := fs.score
FROM
forlan_score fs,( SELECT @cur_rank := 0, @pre_score := NULL ) r
ORDER BY
fs.score DESC;
- 使用自定义变量 + CASE WHEN
SELECT
fs.student_name,
fs.score,
(
CASE
WHEN @pre_score = fs.score THEN @cur_rank
WHEN @pre_score := fs.score THEN @cur_rank := @cur_rank + 1
END
) AS ranking
FROM
forlan_score fs,(SELECT @cur_rank := 0,@pre_score := NULL) r
ORDER BY
fs.score DESC;
2)mysql8实现
DENSE_RANK()
SELECT
student_name,
score,
DENSE_RANK() OVER ( ORDER BY score DESC ) AS ranking
FROM
forlan_score;
2.2、效果
+--------------+-------+---------+
| student_name | score | ranking |
+--------------+-------+---------+
| 小林 | 100 | 1 |
| 小黄 | 100 | 1 |
| 小小 | 100 | 1 |
| 小美 | 90 | 2 |
| 小伟 | 88 | 3 |
| 小东 | 80 | 4 |
| 小明 | 70 | 5 |
| 小红 | 65 | 6 |
+--------------+-------+---------+
3、并列排名,不连续
3.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量 + IF
SELECT
fs.student_name,
fs.score,
@row_num := @row_num + 1,
IF( @pre_score = fs.score, @cur_rank, @cur_rank := @row_num ) AS ranking,
@pre_score := fs.score
FROM
forlan_score fs,
(SELECT @cur_rank := 0,@pre_score := NULL,@row_num := 0 ) r
ORDER BY
fs.score DESC;
- 使用自定义变量 + CASE WHEN
SELECT
fs.student_name,
fs.score,
@row_num := @row_num + 1,
( CASE WHEN @pre_score = fs.score THEN @cur_rank WHEN @pre_score := fs.score THEN @cur_rank := @row_num END ) AS ranking
FROM
forlan_score fs,
( SELECT @cur_rank := 0, @pre_score := NULL, @row_num := 0 ) r
ORDER BY
fs.score DESC;
2)mysql8实现
RANK()
SELECT
student_name,
score,
RANK() OVER ( ORDER BY score DESC ) AS ranking
FROM
forlan_score;
3.2、效果
+--------------+-------+---------+
| student_name | score | ranking |
+--------------+-------+---------+
| 小林 | 100 | 1 |
| 小黄 | 100 | 1 |
| 小小 | 100 | 1 |
| 小美 | 90 | 4 |
| 小伟 | 88 | 5 |
| 小东 | 80 | 6 |
| 小明 | 70 | 7 |
| 小红 | 65 | 8 |
+--------------+-------+---------+
三、按照课程分组实现排名
1、不重复,连续
1.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量 + IF
SELECT
fs.student_name,
fs.course_name,
fs.score,
IF(@cur_couse = course_name, @cur_rank := @cur_rank+1, @cur_rank :=1) AS ranking,
@cur_couse := fs.course_name
FROM
forlan_score fs,
( SELECT @cur_rank := 0, @cur_couse := NULL ) r
ORDER BY
fs.course_name,fs.score DESC;
2)mysql8实现
ROW_NUMBER()
SELECT
student_name,
course_name,
score,
ROW_NUMBER() OVER (PARTITION BY course_name ORDER BY course_name,score DESC) AS ranking
FROM
forlan_score;
1.2、效果
+--------------+-------------+-------+---------+
| student_name | course_name | score | ranking |
+--------------+-------------+-------+---------+
| 小林 | 数学 | 100 | 1 |
| 小小 | 数学 | 100 | 2 |
| 小明 | 数学 | 70 | 3 |
| 小美 | 英语 | 90 | 1 |
| 小伟 | 英语 | 88 | 2 |
| 小红 | 英语 | 65 | 3 |
| 小黄 | 语文 | 100 | 1 |
| 小东 | 语文 | 80 | 2 |
+--------------+-------------+-------+---------+
2、并列排名,连续
2.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量 + IF
SELECT
fs.student_name,
fs.course_name,
fs.score,
IF(@cur_couse = course_name, IF( @pre_score = fs.score, @cur_rank, @cur_rank := @cur_rank+1 ), @cur_rank :=1) AS ranking,
@pre_score := fs.score,
@cur_couse := fs.course_name
FROM
forlan_score fs,
( SELECT @cur_rank := 0, @pre_score := NULL, @cur_couse := NULL ) r
ORDER BY
fs.course_name,fs.score DESC;
2)mysql8实现
DENSE_RANK()
SELECT
student_name,
course_name,
score,
DENSE_RANK() OVER (PARTITION BY course_name ORDER BY course_name,score DESC) AS ranking
FROM
forlan_score;
2.2、效果
+--------------+-------------+-------+---------+
| student_name | course_name | score | ranking |
+--------------+-------------+-------+---------+
| 小林 | 数学 | 100 | 1 |
| 小小 | 数学 | 100 | 1 |
| 小明 | 数学 | 70 | 2 |
| 小美 | 英语 | 90 | 1 |
| 小伟 | 英语 | 88 | 2 |
| 小红 | 英语 | 65 | 3 |
| 小黄 | 语文 | 100 | 1 |
| 小东 | 语文 | 80 | 2 |
+--------------+-------------+-------+---------+
3、并列排名,不连续
3.1、不同版本实现
1)mysql5.7实现
- 使用自定义变量 + IF
SELECT
fs.student_name,
fs.course_name,
fs.score,
IF(@cur_couse = course_name, @row_num := @row_num + 1, @row_num :=1),
IF(@cur_couse = course_name, IF( @pre_score = fs.score, @cur_rank, @cur_rank := @row_num ),@cur_rank :=1) AS ranking,
@pre_score := fs.score,
@cur_couse := fs.course_name
FROM
forlan_score fs,
( SELECT @cur_rank := 0, @pre_score := NULL, @row_num := 0,@cur_couse := NULL ) r
ORDER BY
fs.course_name,fs.score DESC;
2)mysql8实现
RANK()
SELECT
student_name,
course_name,
score,
RANK() OVER (PARTITION BY course_name ORDER BY course_name,score DESC) AS ranking
FROM
forlan_score;
3.2、效果
+--------------+-------------+-------+---------+
| student_name | course_name | score | ranking |
+--------------+-------------+-------+---------+
| 小林 | 数学 | 100 | 1 |
| 小小 | 数学 | 100 | 1 |
| 小明 | 数学 | 70 | 3 |
| 小美 | 英语 | 90 | 1 |
| 小伟 | 英语 | 88 | 2 |
| 小红 | 英语 | 65 | 3 |
| 小黄 | 语文 | 100 | 1 |
| 小东 | 语文 | 80 | 2 |
+--------------+-------------+-------+---------+
MySQL中多种排名实现的更多相关文章
- 小白养成记——MySQL中的排名函数
1.ROW_NUMBER() 函数 依次排序,没有并列名次.如 SELECT st.ID '学号', st.`NAME` '姓名', sc.SCORE '成绩', ROW_NUMBER() OVER( ...
- 在MySQL中实现Rank高级排名函数【转】
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
- 在MySQL中实现Rank高级排名函数
MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名.尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名 ...
- MySQL中的information_schema数据库表说明
MySQL 中的 information_schema 数据库 版权声明:https://blog.csdn.net/kikajack/article/details/80065753 1. 概述 ...
- 【转】MySQL中information_schema是什么
大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_schema数据库. information_schema数据库是做什么用的呢,使用WordPress博客 ...
- 【MySQL】漫谈MySQL中的事务及其实现
最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySQL,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
- [数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁
注明: 本文转载自http://www.hollischuang.com/archives/914 在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的 ...
- mysql中,主键与普通索引
一.什么是索引?索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里 ...
- [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 漫谈MySql中的事务
最近一直在做订单类的项目,使用了事务.我们的数据库选用的是MySql,存储引擎选用innoDB,innoDB对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
随机推荐
- Ubuntu实现电商网站+Mysql主从复制+NFS
Ubuntu实现电商网站+Mysql主从复制+NFS 1.环境准备 提前准备:Mysql8.0.30安装包.Mysql安装脚本.shopxo2.3.0安装包.DNS脚本 服务器 IP地址 作用 系统版 ...
- selenium 添加特殊配置(如不完整 希望各位大神评论告诉我)
options 常用配置 #添加特殊配置 options=webdriver.ChromeOptions() #设置默认编码为utf-8,也就是中文 options.add_argument('lan ...
- MYSQL ---mysql 数据导入与导出
1.使用SQLyog导出MySQL中的数据库 打开SQLyog → 右击你想要保存的数据库 → 选择"Backup/Export"→ 选择"Backup Database ...
- 2022春每日一题:Day 37
题目:[USACO14FEB]Auto-complete S 字典树套路题,字典树优化剪枝,加个cnt标记即可 代码: #include <cstdio> #include <cst ...
- Spring校验器实例
@size (min=3, max=20,message="用户名长度只能在3-20之间") @size (min=6, max=20,message="密码长度只能在6 ...
- MySQL遇到的坑:sql_mode=only_full_group_by不兼容
描述: 解决方案: show variables like "%sql_mode%"; SET sql_mode=(SELECT REPLACE(@@sql_mode," ...
- SpringDataJpa源码理解
SpringDataJpa源码理解 上一篇讲解了SpringDataJpa的基本使用,下面简单说一下源码 我们以其中的一个test为案例进行分析: 我们可以发现resumeDao它是一个代理对象,类型 ...
- 关于mysql命令的学习
前言 这篇文章我不会具体说明哪些操作有哪些命令,我只说明这些命令的记忆方法.其实知道原理后,这些命令尽管多,但都是有据可循的 mysql提示符 可以通过登录时加入 –prompt 提示符内容 参数 登 ...
- 【每日一题】【使用list&使用辅助栈实现】2022年2月11日-NC90 包含min函数的栈
描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop.top 和 min 函数操作时,栈中一定有元素. 此栈包含的方法有:push(value): ...
- 【每日一题】【双指针、位运算】2022年2月3日-NC103 反转字符串
描述 写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串.(字符串长度不超过1000) 答案:双指针 import java.util.*; public class Solution { ...