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对事务有着良好的支持.这篇文章我们一起来扒一扒事务相关的知识. 为什么要有事务? 事务广泛的 ...
随机推荐
- Pictionary 方法记录
[COCI2017-2018#5] Pictionary 题面翻译 题目描述 在宇宙一个不为人知的地方,有一个星球,上面有一个国家,只有数学家居住. 在这个国家有\(n\)个数学家,有趣的是,每个数学 ...
- 【题解】CF374C Inna and Dima
题面传送门 解决思路 本题是找最长路的图上问题,所以先考虑如何建图. 首先把每一个字母转化为数字,然后对于每一个点枚举四个方向,如果有下一个字母,就向那个点建一条边,可以用 \(vector\) 存图 ...
- hwlog----types.go
// Copyright(C) 2021. Huawei Technologies Co.,Ltd. All rights reserved.// Package hwlog provides the ...
- Java-ArrayList应用
存储随机数字 ArrayListRandom.java package cn.day04; import java.util.ArrayList; import java.util.Random; p ...
- Python编程规范之PEP8
Python编程规范-PEP8 PEP是 Python Enhancement Proposal 的缩写. 英文链接: https://legacy.python.org/dev/peps/pep-0 ...
- keras小点记录
Keras学习小点记录 1.axis(轴) (1)解释 参考链接:https://www.zhihu.com/question/58993137 (2)测试 参考链接:http://keras-cn. ...
- v-model双向绑定原理
1 <div id="app"> 2 <div>{{msg}}</div> 3 <!-- 写法1 --> 4 <input t ...
- java时区相关问题(被恶心到了)
在项目开发中,遇到了mysql5.7数据库相关的时区问题.整理如下: 问题一:在使用swagger测试接口时,数据库记录的时间和输入的不一致.如下图: swagger中输入的是:"recei ...
- 网易云VIP音乐NCM文件转MP3,C语言版本。
前言 网易云的Vip音乐下载下来,格式不是mp3/flac这种通用的音乐格式,而是经过加密的ncm文件.只有用网易云的音乐App才能够打开.于是想到可不可以把.ncm文件转换成mp3或者flac文件, ...
- 使用nodejs编写api接口并部署到服务器上
一.用node.js编写api接口 1.安装node环境,没有就去下载nodejs, 下载地址 2.创建一个node项目, 新建一个目录文件,例node_proxy 3.在新建的node项目执行npm ...