新闻资讯  快讯  焦点  财经  政策  社会
互 联 网   电商  金融  数据  计算  技巧
生活百科  科技  职场  健康  法律  汽车
手机百科  知识  软件  修理  测评  微信
软件技术  应用  系统  图像  视频  经验
硬件技术  知识  技术  测评  选购  维修
网络技术  硬件  软件  设置  安全  技术
程序开发  语言  移动  数据  开源  百科
安全防护  资讯  黑客  木马  病毒  移动
站长技术  搜索  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、新建用户:>CREATE USER name IDENTIFIED BY 'ssapdrow';2、更改密码:>SET PASSWORD FOR name=PASSWORD('fdddfd');3、权限管理>SHOW GRANTS...【详细内容】
2019-07-18   MySQL  点击:(3)  评论:(0)  加入收藏
先看结构体:以下代码块是用来连接数据库的通讯过程,要连接MYSQL,必须建立MYSQL实例,通过mysql_init初始化方能开始进行连接.typedef struct st_mysql {NET net; /* Communicati...【详细内容】
2019-07-18   MySQL  点击:(4)  评论:(0)  加入收藏
1、从概念上来讲,它们是不同的,truncate是DDL语句,会隐式提交,所以,不能回滚,不会触发触发器。delete是DML语句,这个操作会被放到 rollback segment中,事务提交后才生效。如果有相应...【详细内容】
2019-07-17   MySQL  点击:(1)  评论:(0)  加入收藏
概述在MySQL数据库中,直到5.7这个版本,开始引入JSON数据类型,在此之前如果想在表中保存JSON格式类型的数据,则需要依靠varchar或者text之类的数据类型,如果在低于5.7版本的数据库...【详细内容】
2019-07-17   MySQL  点击:(2)  评论:(0)  加入收藏
概述今天主要分享一下mysql的数据库规范,仅供参考。从基础、命名、表设计、字段设计、索引设计、sql编写、行为规范几个方面做介绍。 基础规范 1、必须使用InnoDB存储引擎说...【详细内容】
2019-07-17   MySQL  点击:(1)  评论:(0)  加入收藏
48作者 | Python语音识别来源 | 深度学习与python(ID:PythonDC)不管是机器学习、web开发或者爬虫,数据库都是绕不过去的。那么今天我们就来介绍Python如何Mysql数据库进行连...【详细内容】
2019-07-17   MySQL  点击:(0)  评论:(0)  加入收藏
概述今天主要介绍一下mysql数据库一般修改InnoDB redo log事务日志文件大小的步骤,然后用一个实验来演示一下,下面一起来看看吧~基本步骤在MySQL 5.5版本里,如果想修改ib_logfi...【详细内容】
2019-07-16   MySQL  点击:(3)  评论:(0)  加入收藏
前言假设现在我们要向mysql插入500万条数据,如何实现高效快速的插入进去?暂时不考虑数据的获取、网络I/O、以及是否跨机操作,本文将在本地进行数据的插入,单纯从mysql入手,把优化...【详细内容】
2019-07-16   MySQL  点击:(10)  评论:(0)  加入收藏
概述有朋友问怎么去看连接mysql数据库有哪些用户及对应的IP地址等等信息,所以顺便整理了下这块内容,下面是涉及的一些命令。1、查看当前连接到数据库的用户和Host## 查看当前...【详细内容】
2019-07-15   MySQL  点击:(1)  评论:(0)  加入收藏
概述闲来无事,看了下高性能mysql这本书,其中的一些MySQL高级特性写的还不错,在这里总结分享下。01分区表1、分区表限制 一张表最多1024个分区 分区表中无法使用外键约束2、分区...【详细内容】
2019-07-12   MySQL  点击:(10)  评论:(0)  加入收藏
对于Mysql常用的SQL语句比如select、create、insert、update、delete、join、order by、group by等等相信大家都不陌生;但对于一些不是很常用却又十分实用的语句在要使用的...【详细内容】
2019-07-11   MySQL  点击:(9)  评论:(0)  加入收藏
一、MySQL 优点:体积小、速度快、总体拥有成本低,开源;支持多种操作系统;是开源数据库,提供的接口支持多种语言连接操作 ;MySQL的核心程序采用完全的多线程编程。线程是轻量级的进...【详细内容】
2019-07-11   MySQL  点击:(6)  评论:(0)  加入收藏
概述今天主要分享一款MySQL日志分析神器--mysqlsla,对于我们分析mysql数据库的三大日志还不错,这里介绍一下。什么是mysqlsla?Mysqlsla 是daniel-nichter 用perl 写的一个脚本,...【详细内容】
2019-07-11   MySQL  点击:(4)  评论:(0)  加入收藏
应用程序慢如牛,原因多多,可能是网络的原因、可能是系统架构的原因,还有可能是数据库的原因。那么如何提高数据库SQL语句执行速度呢?有人会说性能调优是数据库管理员(DBA)的事,然...【详细内容】
2019-07-11   MySQL  点击:(6)  评论:(0)  加入收藏
介绍获取MySQL分区表信息的几种方法。 1. show create table 表名可以查看创建分区表的create语句。 /*!...*/ 是一种特殊的注释,其他的数据库产品当然不会执行。mysql特殊处...【详细内容】
2019-07-09   MySQL  点击:(6)  评论:(0)  加入收藏
时间存储时间存储是我们在MySQL中最常用的一种存储类型,MySQL为我们提供了timestamp和datetime两种数据类型,那么这两者有什么区别,又该如何进行选择呢timestamp和datetime的...【详细内容】
2019-07-08   MySQL  点击:(19)  评论:(0)  加入收藏
概述前面已经介绍了Oracle如何去获取某用户下的所有表的行数,所以就不介绍了,今天主要分享的是怎么去获取mysql数据库下所有表的数据行数,主要介绍3个方法。1、估算某个数据库...【详细内容】
2019-07-08   MySQL  点击:(6)  评论:(0)  加入收藏
创建用户并授权创建用户CREATE USER 'custom'@'localhost' IDENTIFIED BY 'password'; mysql 8.0 默认身份验证插件为caching_sha2_password,导致很...【详细内容】
2019-07-04   MySQL  点击:(9)  评论:(0)  加入收藏
一、主从数据库的区别从数据库(Slave)是主数据库的备份,当主数据库(Master)变化时从数据库要更新,这些数据库软件可以设计更新周期。这是提高信息安全的手段。主从数据库服务...【详细内容】
2019-07-03   MySQL  点击:(10)  评论:(0)  加入收藏
一、摘要本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持...【详细内容】
2019-07-03   MySQL  点击:(8)  评论:(0)  加入收藏
推荐资讯
相关文章
栏目更新
栏目热门