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对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
随机推荐
- Debian安装WPS的方法
1.防止安装失败,请尽量重启电脑,关闭系统的软件商店,因为商店的权限可能会锁住pkg的配置文件,导致无法安装wps. 2.将原机残废的WPS卸载干净,卸载方法:手动或命令行操作. sudo apt r ...
- Codeforces Round #829 (Div. 2) D. Factorial Divisibility(数学)
题目链接 题目大意: \(~~\)给定n个正整数和一个数k,问这n个数的阶乘之和能不能被k的阶乘整除 既:(a\(_{1}\)!+a\(_{2}\)!+a\(_{3}\)!+....+a\(_{n}\ ...
- 一次SpringBoot版本升级,引发的血案
前言 最近项目组升级了SpringBoot版本,由之前的2.0.4升级到最新版本2.7.5,却引出了一个大Bug. 到底是怎么回事呢? 1.案发现场 有一天,项目组的同事反馈给我说,我之前有个接口在新 ...
- 2022春每日一题:Day 32
题目:[USACO12DEC]First! G 不太记得当时怎么想的了,但是显然,当一个字符串的前缀存在则他一定不是first,然后做法:对于每个字符串,把每个字符结尾跟他有相同前缀的单词的同元素建边 ...
- kotlin的suspend对比csharp的async&await
协程的出现大大降低了异步编程的复杂度,可以让我们像写同步代码一样去写异步代码,如果没有它,那么很多异步的代码都是需要靠回调函数来一层层嵌套,这个在我之前的一篇有介绍 rxjava回调地狱-kotlin ...
- UBOOT编译--- UBOOT的$(version_h) $(timestamp_h)(七)
1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 概述 在编译uboot的过程中,有两个特别的依赖version_h 和 timestamp_h,它们定义 ...
- Linux面试题2:网络IO模型 & IO多路复用
网络IO 先确定一下范围,我们讨论的都是网络IO,现阶段计算机早已经从CPU密集型转换成网络IO密集型,所以网络io的类型对于服务响应而言更重要. 五种IO模型 依据Unix的IO分类,网络IO分为五 ...
- 【终极解决办法】pyinstaller打包exe没有错误,运行exe提示Failed to execute script 'mainlmageWindows' due tounhandled exception: No module named 'docx'
一.通过pyinstaller打包exe可执行文件,由于我的py是多个,所以要先生成spec文件,代码如下: pyi-makespec mainImageWindows.py 此时生产了一个mainI ...
- hexo-gitalk-评论自动初始化
第一步 申请Personal Access Token 从 Github 的 Personal access tokens 页面,点击 Generate new token 第二步 安装项目依赖 np ...
- MVT模型与MVC模型的区别
1. MVC设计模式 MVC 是 Model-View-Controller 的缩写,其中每个单词都有其不同的含义: Modle 代表数据存储层,是对数据表的定义和数据的增删改查: View 代表视图 ...