MySQL中有哪些常见的排名

  

MySQL中有哪些常见的排名?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

<强>前言:

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

<强>创建测试表

创建表scores_tb (
  id int auto_increment主键,
  xuehao int非空,
  分数int非空
  )引擎=InnoDB默认字符集=utf8;
  插入scores_tb (xuehao分数)值(1001、89),(1002、99),(1003、96),(1004、96),(1005、92),(1006、90),(1007、90),(1008、94);
  
  #查看下插入的数据
  mysql>从scores_tb select *;
  + - - - - - - - - - - - - - - - - - - - - - - + +
  | | | id xuehao |分数
  + - - - - - - - - - - - - - - - - - - - - - - + +
  | 1 | 1001 | 89 |
  | 2 | 1002 | 99 |
  | 3 | 1003 | 96 |
  96 | | 1004 | |
  92 | | 1005 | |
  90 | | 1006 | |
  90 | | 1007 | |
  94 | | 1008 | |
  + - - - - - - - - - - - - - - - - - - - - - - + + 

<强> 1。普通排名

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

 #查询语句
  选择xuehao、分数@curRank:=@curRank + 1
  从scores_tb (
  选择@curRank:=0
  r)
  分数desc秩序;
  
  #排序结果
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | xuehao |积分| |
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | 1002 | 99 | 1 |
  | 1003 | 96 | 2 |
  | 1004 | 96 | 3 |
  | 1008 | 94 | 4 |
  | 1005 | 92 | 5 |
  | 1006 | 90 | 6 |
  1007 | | 90 | |
  1001 | | 89 | |
  + - - - - - - - - - - - - - - - - - - - - - - - + + 

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

<强> 2。分数相同,名次相同,排名无间隔

 #查询语句
  选择xuehao,分数,
  情况下
  当@prevRank=分数然后@curRank
  当@prevRank:=分数然后@curRank:=@curRank + 1
  结束,排名
  从scores_tb,
  (选择@curRank:=0, @prevRank:=NULL) r
  分数desc秩序;
  
  #排名结果
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | xuehao |积分| |
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | 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。并列排名,排名有间隔

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

 #查询语句
  选择xuehao、分数排名
  (选择xuehao,分数,
  @curRank:=如果(@prevRank=分数,@curRank, @incRank)排名,
  @incRank:=@incRank + 1,
  @prevRank:=分数
  从scores_tb (
  选择@curRank:=0, @prevRank:=NULL, @incRank:=1
  r)
  按分数desc);
  #排名结果
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | xuehao |积分| |
  + - - - - - - - - - - - - - - - - - - - - - - - + +
  | 1002 | 99 | 1 |
  | 1003 | 96 | 2 |
  | 1004 | 96 | 2 |
  | 1008 | 94 | 4 |
  | 1005 | 92 | 5 |
  | 1006 | 90 | 6 |
  | 1007 | 90 | 6 |
  1001 | | 89 | |
  + - - - - - - - - - - - - - - - - - - - - - - - + + 

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

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

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

 #三条语句对于上面三种排名
  选择xuehao、分数ROW_NUMBER()(按分数desc)从scores_tb row_r;
  选择xuehao、分数DENSE_RANK()/(按分数desc)从scores_tb dense_r;
  选择xuehao,分数,排名()/(按分数desc) r scores_tb;
  
  #一条语句也可以查询出不同排名
  选择xuehao,分数,
  ROW_NUMBER ()/w & # 39; row_r& # 39;
  DENSE_RANK ()/w & # 39; dense_r& # 39;
  排名()/w & # 39; " # 39;
  从“scores_tb”
  窗口w(按“分数”desc);
  
  #排名结果
  + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - + - - - +
  | xuehao |积分| row_r | dense_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 |
  + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - - - + 

MySQL中有哪些常见的排名