在MySQL中实现Rank高级排名函数

原文链接

MySQL中没有Rank排名函数,当我们需要查询排名时,只能使用MySQL数据库中的基本查询语句来查询普通排名。尽管如此,可不要小瞧基础而简单的查询语句,我们可以利用其来达到Rank函数一样的高级排名效果。

在这里我用一个简单例子来实现排名的查询:

首先我们先创建一个我们需要进行高级排名查询的players表,

CREATE TABLE players (
pid int(2) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
age int(2) NOT NULL,
PRIMARY KEY (pid),
UNIQUE KEY name (name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO players (pid, name, age) VALUES
(1, ‘Samual’, 25),
(2, ‘Vino’, 20),
(3, ‘John’, 20),
(4, ‘Andy’, 22),
(5, ‘Brian’, 21),
(6, ‘Dew’, 24),
(7, ‘Kris’, 25),
(8, ‘William’, 26),
(9, ‘George’, 23),
(10, ‘Peter’, 19),
(11, ‘Tom’, 20),
(12, ‘Andre’, 20);
1、在MySQL中实现Rank普通排名函数
在这里,我们希望获得一个排名字段的列,以及age的升序排列。所以我们的查询语句将是:

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age

PIDNAMEAGERANK
10Peter191
12Andre202
2Vino203
3John204
11Tom205
5Brian216
4Andy227
9George238
6Dew249
7Kris2510
1Samual2511
8William2612

要在mysql中声明一个变量,你必须在变量名之前使用@符号。FROM子句中的(@curRank := 0)部分允许我们进行变量初始化,而不需要单独的SET命令。当然,也可以使用SET,但它会处理两个查询:

SET @curRank := 0;
SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players
ORDER BY age
2、查询以降序排列
首要按age的降序排列,其次按name进行排列,只需修改查询语句加上ORDER BY和 DESC以及列名即可。

SELECT pid, name, age, @curRank := @curRank + 1 AS rank
FROM players p, (
SELECT @curRank := 0
) q
ORDER BY age DESC, name

PIDNAMEAGERANK
8William261
7Kris252
1Samual253
6Dew244
9George235
4Andy226
5Brian217
12Andre208
3John209
11Tom2010
2Vino2011
10Peter1912

3、在MySQL中实现Rank普通并列排名函数
现在,如果我们希望为并列数据的行赋予相同的排名,则意味着那些在排名比较列中具有相同值的行应在MySQL中计算排名时保持相同的排名(例如在我们的例子中的age)。为此,我们使用了一个额外的变量。

SELECT pid, name, age,
CASE
WHEN @prevRank = age THEN @curRank
WHEN @prevRank := age THEN @curRank := @curRank + 1
END AS rank
FROM players p,
(SELECT @curRank :=0, @prevRank := NULL) r
ORDER BY age

PIDNAMEAGERANK
10Peter191
12Andre202
2Vino202
3John202
11Tom202
5Brian213
4Andy224
9George235
6Dew246
7Kris257
1Samual257
8William268

如上所示,具有相同数据和排行的两行或多行,它们都会获得相同的排名。玩家Andre, Vino, John 和Tom都有相同的age,所以他们排名并列第二。下一个最高age的玩家(Brian)排名第3。这个查询相当于MSSQL和ORACLE 中的DENSE_RANK()函数。

4、在MySQL中实现Rank高级并列排名函数
当使用RANK()函数时,如果两个或以上的行排名并列,则相同的行都会有相同的排名,但是实际排名中存在有关系的差距。

SELECT pid, name, age, rank FROM
(SELECT pid, name, age,
@curRank := IF(@prevRank = age, @curRank, @incRank) AS rank,
@incRank := @incRank + 1,
@prevRank := age
FROM players p, (
SELECT @curRank :=0, @prevRank := NULL, @incRank := 1
) r
ORDER BY age) s
这是一个查询中的子查询。我们使用三个变量(@incRank,@prevRank,@curRank)来计算关系的情况下,在查询结果中我们已经补全了因为并列而导致的排名空位。我们已经封闭子查询到查询。这个查询相当于MSSQL和ORACLE中的RANK()函数。

PIDNAMEAGERANK
10Peter191
12Andre202
2Vino202
3John202
11Tom202
5Brian216
4Andy227
9George238
6Dew249
7Kris2510
1Samual2510
8William2612

在这里我们可以看到,Andre,Vino,John和Tom都有相同的age,所以他们排名并列第二。下一个最高年龄的球员(Brian)排名第6,而不是第3,因为有4个人并列排名在第2。

好的,我希望在这些例子后,能让你了解RANK()和DENSE_RANK()之间的区别,并且知道在哪里应使用哪个查询来获取MySQL中的rank函数。谢谢。

via http://fellowtuts.com/mysql/query-to-obtain-rank-function-in-mysql

作者:风澈vio
链接:https://www.jianshu.com/p/bb1b72a1623e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值