前言:?

在某些应用场景中,我们经常会遇到一些排名的问题,比如按成绩或年龄排名。排名也有多种排名方式,如直接排名、分组排名,排名有间隔或排名无间隔等等,这篇文章将总结几种MySQL中常见的排名问题。

创建测试表

create table scores_tb (

id int auto_increment primary key,

xuehao int not null,

score int not null

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into scores_tb (xuehao,score) values (1001,89),(1002,99),(1003,96),(1004,96),(1005,92),(1006,90),(1007,90),(1008,94);

# 查看下插入的数据

mysql> select * from scores_tb;

+----+--------+-------+

| id | xuehao | score |

+----+--------+-------+

| 1 | 1001 | 89 |

| 2 | 1002 | 99 |

| 3 | 1003 | 96 |

| 4 | 1004 | 96 |

| 5 | 1005 | 92 |

| 6 | 1006 | 90 |

| 7 | 1007 | 90 |

| 8 | 1008 | 94 |

+----+--------+-------+

1.普通排名

按分数高低直接排名,从1开始,往下排,类似于row number。下面我们给出查询语句及排名结果。

# 查询语句

SELECT xuehao, score, @curRank := @curRank + 1 AS rank

FROM scores_tb, (

SELECT @curRank := 0

) r

ORDER BY score desc;

# 排序结果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

| 1002 | 99 | 1 |

| 1003 | 96 | 2 |

| 1004 | 96 | 3 |

| 1008 | 94 | 4 |

| 1005 | 92 | 5 |

| 1006 | 90 | 6 |

| 1007 | 90 | 7 |

| 1001 | 89 | 8 |

+--------+-------+------+

上述查询语句中,我们申明了一个变量 @curRank?,并将此变量初始化为0,查得一行将此变量加一,并以此作为排名。我们看到这类排名是没间隔的并且有些分数相同但排名不同。

2.分数相同,名次相同,排名无间隔

# 查询语句

SELECT xuehao, score,

CASE

WHEN @prevRank = score THEN @curRank

WHEN @prevRank := score THEN @curRank := @curRank + 1

END AS rank

FROM scores_tb,

(SELECT @curRank :=0, @prevRank := NULL) r

ORDER BY score desc;

# 排名结果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

| 1002 | 99 | 1 |

| 1003 | 96 | 2 |

| 1004 | 96 | 2 |

| 1008 | 94 | 3 |

| 1005 | 92 | 4 |

| 1006 | 90 | 5 |

| 1007 | 90 | 5 |

| 1001 | 89 | 6 |

+--------+-------+------+

3.并列排名,排名有间隔

另外一种排名方式是相同的值排名相同,相同值的下一个名次应该是跳跃整数值,即排名有间隔。

# 查询语句

SELECT xuehao, score, rank FROM

(SELECT xuehao, score,

@curRank := IF(@prevRank = score, @curRank, @incRank) AS rank,

@incRank := @incRank + 1,

@prevRank := score

FROM scores_tb, (

SELECT @curRank :=0, @prevRank := NULL, @incRank := 1

) r

ORDER BY score desc) s;

# 排名结果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

| 1002 | 99 | 1 |

| 1003 | 96 | 2 |

| 1004 | 96 | 2 |

| 1008 | 94 | 4 |

| 1005 | 92 | 5 |

| 1006 | 90 | 6 |

| 1007 | 90 | 6 |

| 1001 | 89 | 8 |

+--------+-------+------+

上面介绍了三种排名方式,实现起来还是比较复杂的。好在MySQL8.0增加了窗口函数,使用内置函数可以轻松实现上述排名。

MySQL8.0 利用窗口函数实现排名

MySQL8.0中可以利用?ROW_NUMBER(),DENSE_RANK(),RANK()?三个窗口函数实现上述三种排名,需要注意的一点是as后的别名,千万不要与前面的函数名重名,否则会报错,下面给出这三种函数实现排名的案例:

# 三条语句对于上面三种排名

select xuehao,score, ROW_NUMBER() OVER(order by score desc) as row_r from scores_tb;

select xuehao,score, DENSE_RANK() OVER(order by score desc) as dense_r from scores_tb;

select xuehao,score, RANK() over(order by score desc) as r from scores_tb;

# 一条语句也可以查询出不同排名

SELECT xuehao,score,

ROW_NUMBER() OVER w AS ‘row_r‘,

DENSE_RANK() OVER w AS ‘dense_r‘,

RANK() OVER w AS ‘r‘

FROM `scores_tb`

WINDOW w AS (ORDER BY `score` desc);

# 排名结果

+--------+-------+-------+---------+---+

| xuehao | score | row_r | dense_r | r |

+--------+-------+-------+---------+---+

| 1002 | 99 | 1 | 1 | 1 |

| 1003 | 96 | 2 | 2 | 2 |

| 1004 | 96 | 3 | 2 | 2 |

| 1008 | 94 | 4 | 3 | 4 |

| 1005 | 92 | 5 | 4 | 5 |

| 1006 | 90 | 6 | 5 | 6 |

| 1007 | 90 | 7 | 5 | 6 |

| 1001 | 89 | 8 | 6 | 8 |

+--------+-------+-------+---------+---+

总结:?

本文给出三种不同场景下实现统计排名的SQL,可以根据不同业务需求选取合适的排名方案。对比MySQL8.0,发现利用窗口函数可以更轻松实现排名,其实业务需求远远比我们举的示例要复杂许多,用SQL实现此类业务需求还是需要慢慢积累的。

参考:?

mysql 计算排名_教你用SQL实现统计排名相关推荐

  1. mysql sql并列排名_教你用SQL实现统计排名

    前言: 在某些应用场景中,我们经常会遇到一些排名的问题,比如按成绩或年龄排名.排名也有多种排名方式,如直接排名.分组排名,排名有间隔或排名无间隔等等,这篇文章将总结几种MySQL中常见的排名问题. 创 ...

  2. mysql trunc函数_教您使用SQL中的TRUNC函数

    SQL函数是每个SQL数据库使用者都必须要掌握的,下面就将为您介绍SQL中TRUNC函数的两种用法,供您参考,希望对您学习SQL函数的使用能有帮助. 1.TRUNC(for dates) TRUNC函 ...

  3. mysql 廖雪峰_廖雪峰大佬SQL教程学习笔记

    1,SQL(Structured Query Language),就是访问和处理(操作)关系数据库的计算机标准语言.SQL语句既可以查询数据库中的数据,也可以添加,更新和删除数据库中的数据,还可以对数 ...

  4. mysql计算秒_如何在MySQL中基于秒计算时间?

    让我们首先创建一个表-mysql> create table DemoTable ( Logouttime time ); 使用插入命令在表中插入一些记录-mysql> insert in ...

  5. mysql语句随机数_程序生成随机数与SQL语句生成随机数

    随机数可以通过程序生成,也可以通过SQL语句生成.通过程序生成随机数时一般采用硬件的编号+时间作为种子,这种方法在瞬间插入数据库N条数据的时候会影响随机数的效果,生成很多相邻的插入值相同.所以频繁插入 ...

  6. mysql 插入秒_教你88秒插入1000万条数据到mysql数据库表,IG牛逼

    我用到的数据库为,mysql数据库5.7版本的首先自己准备好数据库表 其实我在插入1000万条数据的时候遇到了一些问题,现在先来解决他们,一开始我插入100万条数据时候报错,控制台的信息如下: com ...

  7. mysql 时区设定_教你如何修改mysql时区的问题

    前言 最近公司项目上实现一个新需求,本地已经测通了没问题,放到服务器上就出现毛病了,时间错了. 问题是什么? 需求是让统计24个小时(以当前时间为准向前推24个小时)的数据.SQL语句大概是这样: S ...

  8. 学生选课在MYSQL创建表_学生选课数据库SQL语句练习题

    一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...

  9. mysql 递归查询 效率_性能优化实战-sql递归查询效率低下

    今天在做一个热门赛事列表查询的接口压测 http://192.168.10.98:8094/match/page?matchType=0&matchTime=0&matchStatus ...

最新文章

  1. 用例设计方法及其覆盖率
  2. aspose-cells 表合并
  3. FreeMarker简介及其语法
  4. 010_html事件属性
  5. MathType输入补集符号的步骤有哪些
  6. ios raise_如何在iOS 10中关闭“ Raise to Wake”
  7. 分治法的关键特征_经典算法思想2——分治(Divide-and-Conquer)
  8. 95-10-140-启动-权限
  9. Linux ag命令
  10. DFA算法实现 敏感词过滤
  11. 频谱图 与傅立叶变换
  12. 运维工程师种种尴尬的瞬间情景,你有无?
  13. 黑白方格画C++解答
  14. 计算机主板现状及发展趋势论文,2020年计算机主板发展趋势分析 2020-2026年全球与中国计算机主板市场深度调研与发展趋势分析...
  15. 计算机提示找不到系统文件,为何我的电脑一开机就显示Windows找不到文件
  16. 【日常学习】XML文件约束,Tomcat服务器和HTTP协议
  17. day007-列表和字典
  18. IT审计?CISA?
  19. doris安装部署-通过docker部署doris集群
  20. 使用CocosCreator完成2048小游戏demo

热门文章

  1. java静态代码检测 pmd,PMD使用与代码质量
  2. sql查询文章上一篇下一篇
  3. PHP获取上一篇文章和下一篇文章数据
  4. android解决 Button 和 TabLayout 英文自动大写的问题
  5. 简单暴力解决navicat中文字符集乱码问题
  6. Framework 全局监听屏幕点击事件 INPUT_EVENT_INJECTION
  7. Java实现一个简单的两人五子棋游戏(六) 行棋方变换
  8. 快讯:银行地产股跳水 沪指跌幅扩大
  9. 拉格朗日乘数法及python实现拉格朗日乘数法
  10. 2019纪中Day four