博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在MySQL中实现Rank高级排名函数
阅读量:5845 次
发布时间:2019-06-18

本文共 3753 字,大约阅读时间需要 12 分钟。

转载于:

ySQL中没有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 rankFROM players p, (SELECT @curRank := 0) qORDER BY age

 

| PID |    NAME | AGE | RANK ||-----|---------|-----|------| | 10 | Peter | 19 | 1 | | 12 | Andre | 20 | 2 | | 2 | Vino | 20 | 3 | | 3 | John | 20 | 4 | | 11 | Tom | 20 | 5 | | 5 | Brian | 21 | 6 | | 4 | Andy | 22 | 7 | | 9 | George | 23 | 8 | | 6 | Dew | 24 | 9 | | 7 | Kris | 25 | 10 | | 1 | Samual | 25 | 11 | | 8 | William | 26 | 12 |

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

SET @curRank := 0;SELECT pid, name, age, @curRank := @curRank + 1 AS rankFROM playersORDER BY age

 


2、查询以降序排列

首要按age的降序排列,其次按name进行排列,只需修改查询语句加上ORDER BYDESC以及列名即可。

SELECT pid, name, age, @curRank := @curRank + 1 AS rankFROM players p, (SELECT @curRank := 0) qORDER BY age DESC, name

 

| PID |    NAME | AGE | RANK ||-----|---------|-----|------| | 8 | William | 26 | 1 | | 7 | Kris | 25 | 2 | | 1 | Samual | 25 | 3 | | 6 | Dew | 24 | 4 | | 9 | George | 23 | 5 | | 4 | Andy | 22 | 6 | | 5 | Brian | 21 | 7 | | 12 | Andre | 20 | 8 | | 3 | John | 20 | 9 | | 11 | Tom | 20 | 10 | | 2 | Vino | 20 | 11 | | 10 | Peter | 19 | 12 |

3、在MySQL中实现Rank普通并列排名函数

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

SELECT pid, name, age, #将age的每行记录依次代入与@prevRank进行比较,若相等则执行then后面的语句@prevRank = age THEN @curRank #若age的记录与@prevRank不相等,则将age赋值给@prevRank,然后@curRank加1WHEN @prevRank age THEN @curRank := @curRank + 1END AS rankFROM players p, (SELECT @curRank :=0, @prevRank := NULL) rORDER BY age

 

| PID |    NAME | AGE | RANK ||-----|---------|-----|------| | 10 | Peter | 19 | 1 | | 12 | Andre | 20 | 2 | | 2 | Vino | 20 | 2 | | 3 | John | 20 | 2 | | 11 | Tom | 20 | 2 | | 5 | Brian | 21 | 3 | | 4 | Andy | 22 | 4 | | 9 | George | 23 | 5 | | 6 | Dew | 24 | 6 | | 7 | Kris | 25 | 7 | | 1 | Samual | 25 | 7 | | 8 | William | 26 | 8 |

如上所示,具有相同数据和排行的两行或多行,它们都会获得相同的排名。玩家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 := ageFROM players p, (SELECT @curRank :=0, @prevRank := NULL, @incRank := 1) r ORDER BY age) s

 

这是一个查询中的子查询。我们使用三个变量(@incRank,@prevRank,@curRank)来计算关系的情况下,在查询结果中我们已经补全了因为并列而导致的排名空位。我们已经封闭子查询到查询。这个查询相当于MSSQL和ORACLE中的RANK()函数。

| PID |    NAME | AGE | RANK ||-----|---------|-----|------| | 10 | Peter | 19 | 1 | | 12 | Andre | 20 | 2 | | 2 | Vino | 20 | 2 | | 3 | John | 20 | 2 | | 11 | Tom | 20 | 2 | | 5 | Brian | 21 | 6 | | 4 | Andy | 22 | 7 | | 9 | George | 23 | 8 | | 6 | Dew | 24 | 9 | | 7 | Kris | 25 | 10 | | 1 | Samual | 25 | 10 | | 8 | William | 26 | 12 |

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

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

转载于:https://www.cnblogs.com/MarsDing/p/9872023.html

你可能感兴趣的文章
SPOJ 1182 Sorted bit squence
查看>>
谈谈android的类xp Ghost时代
查看>>
使用Filter跟踪Asp.net MVC页面加载时间
查看>>
python学习(五)列表
查看>>
使用GHOST对Windows操作系统进行备份和还原
查看>>
KMeans (K均值)算法讲解及实现
查看>>
23种设计模式之装饰者模式
查看>>
为什么不应该使用Zookeeper做服务发现?(转载)
查看>>
seajs 模块源码解读
查看>>
浅谈分布式CAP定理
查看>>
【Nginx源码研究】初探nginx HTTP处理流程
查看>>
PHP To Go 转型手记 (一)
查看>>
目标检测算法——YOLOV1解析
查看>>
Vue源码探究-类初始化函数详情
查看>>
一个常年更新的CSS采坑合集
查看>>
PowerShell 学习笔记 - 4 Provider, ItemProperty 与 ACL
查看>>
java中字符串的比较
查看>>
vue中使用cookies和crypto-js实现记住密码和加密
查看>>
Slog14_支配vue框架模版语法之v-if
查看>>
Docker 数据管理
查看>>