vlambda博客
学习文章列表

Mysql实现rank排名的3种写法

团队的绩效考核规则变化后,每周Bonus规则也发生了变化,排名前5的员工可以拿到Bonus。


为了使排名能够一目了然,小骨就考虑是否能在考核指标旁边加上“排名”字段。


虽然Mysql没有rank函数,但依然可以通过变量和if函数来实现排名功能!


变量功能请参考《



随手摘了一段社群的积分表来做栗子,看着熟悉的名字好亲切[]~( ̄▽ ̄)~*


下面就由简到难地介绍Rank的3种写法!


Mysql实现rank排名的3种写法
方法一:按顺序排名递增

SELECT idname, score, @curRank := @curRank+1 'rank'FROM `tb_scores` ,(SELECT @curRank := 0)rORDER BY score DESC


之前一直以为“:”是跟在变量后面表示赋值,今天才知道是“:=”表示赋值。

被自己蠢哭Mysql实现rank排名的3种写法Mysql实现rank排名的3种写法Mysql实现rank排名的3种写法


语句其实很简单,就是加了个curRank变量,根据score倒序,从1往后编号。


Mysql实现rank排名的3种写法


问题也很明显,如果score相同,不会对排名进行处理。


Mysql实现rank排名的3种写法
方法二:按顺序排名递增,相同排名不跳级

SELECT id,name,score, CASEWHEN @preRank = score THEN @curRankWHEN @preRank := score THEN @curRank:= @curRank+1END 'rank'FROM `tb_scores` ,(SELECT @curRank := 0, @preRank := NULL) rORDER BY score DESC


多引入了一个变量“preRank”来储存score,如果某个score与上个score相同,则用CASE WHEN给一个相同的“curRank”。


其实放在循环代码里挺好理解的,在Mysql里的写法总觉得怪怪的。


不习惯看CASE WHEN还可以用IF。

这里的IF函数和excel里的用法一样。


SELECT id,name,score, IF(@preRank = score,@curRank,@curRank:= @curRank+1) 'rank'FROM `tb_scores`,(SELECT @curRank := 0, @preRank := NULL) rORDER BY score DESC


Mysql实现rank排名的3种写法


这里可以看到积分相同的小豆子和熊猫有了相同的排名,如果他俩占俩名次,那么苏菲应该排在第10名。


这种要怎么来写呢?


Mysql实现rank排名的3种写法
方法三:按顺序排名递增,相同排名跳级

SELECT id,name,score, @curRank:=IF(@preRank = score,@curRank,@curRank:= @incRank) 'rank',@incRank:=@incRank +1,@preRank:= scoreFROM `tb_scores` ,(SELECT @curRank := 0, @preRank := NULL,@incRank:=1) rORDER BY score DESC


再加入一个“incRank”变量来储存名次,进行占位。


从下图可以很清晰地到看到语句的工作逻辑。


Mysql实现rank排名的3种写法


如果只需要前四列,就在外层再套一层SELECT。


Mysql实现rank排名的3种写法


当把语句用到实际工作场景里,就变成了大型套娃现场Mysql实现rank排名的3种写法Mysql实现rank排名的3种写法



让我不禁回想起学代码时三大经典语句之一:


禁止禁止套娃!