新闻资讯  快讯  焦点  财经  政策  社会
互 联 网   电商  金融  数据  计算  技巧
生活百科  科技  职场  健康  法律  汽车
手机百科  知识  软件  修理  测评  微信
软件技术  应用  系统  图像  视频  经验
硬件技术  知识  技术  测评  选购  维修
网络技术  硬件  软件  设置  安全  技术
程序开发  语言  移动  数据  开源  百科
安全防护  资讯  黑客  木马  病毒  移动
站长技术  搜索  SEO  推广  媒体  移动
财经百科  股票  知识  理财  财务  金融
教育考试  育儿  小学  高考  考研  留学
您当前的位置:首页 > IT百科 > 数据库 > MYSQL

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

时间:2019-05-14 09:28:25  来源:  作者:

MySQL中没有Rank排名函数

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

【MySQL】在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
| 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 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

结果

| 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, 
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

结果

| 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 := age
FROM 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。
 



Tags:MySQL   点击:()  评论:()
声明:本站部分内容来自互联网,内容观点仅代表作者本人,如有任何版权侵犯请与我们联系,我们将立即删除。
▌相关评论
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表
▌相关推荐
1、字符串拼接SELECT CONCAT('My','S','QL') 2、字符串比较SELECT STRCMP('abc','abd'),STRCMP('abc','abc'),S...【详细内容】
2020-03-19   MySQL  点击:(3)  评论:(0)  加入收藏
这个是公司技术基础建设的一部分,在以后我会逐步推出更多的技术相关文章,感觉有用的请关注。这个文章是为了规范公司的数据库使用的,如果公司有原来使用的规范可以做下对比。这...【详细内容】
2020-03-18   MySQL  点击:(8)  评论:(0)  加入收藏
概述很长一段时间,MySQL 执行 连接 的唯一算法是 嵌套循环算法 ( nested loop algorithm) 的变体 ,但是 嵌套循环算法 在某些场景下非常低效,也是 MySQL 一直被诟病的一个问...【详细内容】
2020-03-18   MySQL  点击:(2)  评论:(0)  加入收藏
聚集索引和二级索引每张使用 InnoDB 作为存储引擎的表都有一个特殊的索引称为聚集索引,它保存着每一行的数据,通常,聚集索引就是主键索引。为了得到更高效的查询、插入以及其他...【详细内容】
2020-03-16   MySQL  点击:(4)  评论:(0)  加入收藏
行锁的三种算法InnoDB存储引擎有3种行锁的算法,其分别是: Record Lock:单个行记录上的范围 Gap Lock:间隙锁,锁定一个范围,但不包含记录本身 Next-Key Lock:Gap Lock + Record Loc...【详细内容】
2020-03-16   MySQL  点击:(4)  评论:(0)  加入收藏
《深入理解Java虚拟机》但要想真的深入理解虚拟机一问肯定远远不够的,但是本文中分三部分对JVM有深入的解析。第1章 走近Java第2章 Java内存区域与内存溢出异常第3章 垃圾收...【详细内容】
2020-03-16   MySQL  点击:(6)  评论:(0)  加入收藏
前言随着系统的运行,数据量变得越来越大,单纯的将数据存储在mysql中,已然不能满足查询要求了,此时我们引入Redis作为查询的缓存层,将业务中的热数据保存到Redis,扩展传统关系型数...【详细内容】
2020-03-16   MySQL  点击:(8)  评论:(0)  加入收藏
导论笔者的毕业设计是一个与大数据相关的项目,其中遇到了一个将百万级别数据存储到MySQL 的问题,本来是打算使用Spark SQL 的DataFrame 自带的API来直接将数据存储到MySQL 中,...【详细内容】
2020-03-16   MySQL  点击:(2)  评论:(0)  加入收藏
本文介绍如何利用python来对MySQL数据库进行操作,本文将主要从以下几个方面展开介绍:1.数据库介绍2.MySQL数据库安装和设置3.Python操作MySQL在Python3.X上安装MySQL驱动创建...【详细内容】
2020-03-15   MySQL  点击:(11)  评论:(0)  加入收藏
window7下的mysql的数据;C:\ProgramData\MySQL\MySQL Server 5.1\data如果是mysql同版本的数据库,直接备份这个文件夹的数据即可。如果是不同版本,可以导出sql脚本后再重新导...【详细内容】
2020-03-15   MySQL  点击:(8)  评论:(0)  加入收藏
一,首先还是登录到我们的服务器服务器如何登录我在上一节已经讲过了,大家只需要去看我上一节课程即可。 然后通过下面命令行,检测服务器上是否安装过mysqlrpm -qa|grep mysql如...【详细内容】
2020-03-13   MySQL  点击:(2)  评论:(0)  加入收藏
需要搞清楚pt-query工具Anemometer基于pt-query-digest将MySQL慢查询可视化percona-toolkit工具的安装安装目的:pt-query-digest是percona-toolkit里面一个工具,其作用就是分...【详细内容】
2020-03-13   MySQL  点击:(2)  评论:(0)  加入收藏
MySQL编码过程MySQL出现乱码的原因有很多,一般与character_set参数有关。我们先来看看有哪些参数:SHOW VARIABLES LIKE "character%";Variable_name Value character_set_clie...【详细内容】
2020-03-12   MySQL  点击:(7)  评论:(0)  加入收藏
在满足对某张表中数据的增、删、改的情况下,自动触发的功能称之为触发器。视图就是通过查询得到一张虚拟表,然后将标结果保存下来,下次直接使用即可。索引在MySQL中也叫做“键...【详细内容】
2020-03-12   MySQL  点击:(7)  评论:(0)  加入收藏
Django 默认使用 SQLite3 数据库,而在稍中大型的项目中大多使用 MySQL,因此我们安装 MySQL 进行后续的开发。步骤 1 MySQL 安装文件地址为 https://pan.baidu.com/s/1eSiy6Fw,...【详细内容】
2020-03-10   MySQL  点击:(8)  评论:(0)  加入收藏
MySQL 里有个东西叫 MRR,全称「Multi-Range Read Optimization」。简单说,MRR 通过: 把「随机磁盘读」,转化为「顺序磁盘读」从而: 提高了磁盘读取的性能至于: 为什么要把随机读转...【详细内容】
2020-03-10   MySQL  点击:(12)  评论:(0)  加入收藏
一、MHA原理1、简介:MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MyS...【详细内容】
2020-03-10   MySQL  点击:(7)  评论:(0)  加入收藏
在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。在数据库的锁机制中介绍过,在DBMS中,可以按照锁的粒度把数据库锁...【详细内容】
2020-03-10   MySQL  点击:(8)  评论:(0)  加入收藏
谁在消耗cpu?用户+系统+IO等待+软硬中断+空闲 祸首是谁?用户用户空间CPU消耗,各种逻辑运算正在进行大量tps函数/排序/类型转化/逻辑IO访问…用户空间消耗大量cpu,产生...【详细内容】
2020-03-09   MySQL  点击:(7)  评论:(0)  加入收藏
双mysql,只是在节约成本的前提下,考虑使用的,更多的是在开发测试环境使用,若是生产环境,尽量不建议如此使用。若是生产环境,森哥不建议双MySQL共存。而且,尽量建议使用提供商提供的...【详细内容】
2020-03-08   MySQL  点击:(3)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条