Mysql常用函数之Rank排名函数详解

 更新时间:2024年01月04日 10:37:34   作者:pan_mlpan  
这篇文章主要介绍了Mysql常用函数之Rank排名函数详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

mysql中的排名函数

主要介绍一下mysql里面的排名函数,涉及到的函数有以下几个:

rank()、dense_rank()、row_number()

1、准备工作

建立一个rank表:

create table rank(
	id int(10) not null primary key,
	name varchar(20) not null,
	score int(10) not null
);

插入一些数据:

insert into rank values(1,'a',100);
insert into rank values(2,'b',100);
insert into rank values(3,'c',95);
insert into rank values(4,'d',95);
insert into rank values(5,'e',95);
insert into rank values(6,'a',90);
insert into rank values(7,'a',89);

表及数据的截图:

2、rank() 函数

语法结构:

RANK() OVER (
    PARTITION BY <expression>[{,<expression>...}]
    ORDER BY <expression> [ASC|DESC], [{,<expression>...}]
) 

按照某字段的排序结果添加排名,但它是跳跃的、间断的排名

(1)若按照分数直接进行排序的话,例如按照score进行排名

两个并列第一名后,下一个是第三名。

SELECT score, rank() over(ORDER BY score desc) as 'Rank' 
FROM rank;

结果:

+------+---------+
| score|   Rank  |
+------+---------+
|  100 |       1 |
|  100 |       1 |
|  95  |       3 |
|  95  |       3 |
|  95  |       3 |
|  90  |       6 |
|  89  |       7 |
+------+---------+
7 rows in set (0.02 sec)

(2)若按照某个字段分区进行排序的话,例如按照name进行分区,根据分数进行排名:

SELECT name , 
	score ,
	rank() over(partition by name ORDER BY score desc) as 'Rank' 
	FROM rank;

首先,PARTITION BY子句按姓名将结果集分成多个分区。

然后,ORDER BY子句按分数对结果集进行排序。

结果:

+------+------+---------+
| name | score|   Rank  |
+------+------+---------+
|  a   |  100 |       1 |
|  a   |  90  |       2 |
|  a   |  89  |       3 |
|  b   |  100 |       1 |
|  c   |  95  |       1 |
|  d   |  95  |       1 |
|  e   |  95  |       1 |
+------+------+---------+
7 rows in set (0.02 sec)

3、row_number() 函数

MySQL ROW_NUMBER()从8.0版开始引入了功能。这ROW_NUMBER()是一个窗口函数或分析函数,它为从1开始应用的每一行分配一个序号

语法结构如下:

ROW_NUMBER() OVER (
    PARTITION BY <expression>[{,<expression>...}]
    ORDER BY <expression> [ASC|DESC], [{,<expression>...}]

例如还是根据分数进行排序

SELECT 
 row_number() OVER (
 ORDER BY score
 ) row_num,
 score
 FROM rank;

结果:

+-------+------+---------+
|row_num| score|   Rank  |
+------ +------+---------+
|  1    |  100 |       1 |
|  2    |  100 |       2 |
|  3    |  95  |       3 |
|  4    |  95  |       1 |
|  5    |  95  |       1 |
|  6    |  90  |       1 |
|  7    |  89  |       1 |
+-------+------+---------+
7 rows in set (0.02 sec)

其次,使用ROW_NUMBER()函数将行划分为所有列的分区。对于每个唯一的行集,将重新开始行号。

SELECT 
    id,
    name,
    ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS row_num
FROM rank; 

结果:

+------+------+---------+
| id   | name | row_num |
+------+------+---------+
|    1 | a    |       1 |
|    2 | a    |       2 |
|    3 | a    |       3 |
|    4 | b    |       1 |
|    5 | c    |       1 |
|    6 | d    |       1 |
|    7 | e    |       1 |
+------+------+---------+
7 rows in set (0.02 sec)

4、dense_rank() 函数

dense 英语中指“稠密的、密集的”。dense_rank()是的排序数字是连续的、不间断。当有相同的分数时,它们的排名结果是并列的,例如,1,2,2,3。

语法结构:

DENSE_RANK() OVER (
    PARTITION BY <expression>[{,<expression>...}]
    ORDER BY <expression> [ASC|DESC], [{,<expression>...}]
) 

例如,还是根据成绩进行排名:

SELECT score, dense_rank() over(ORDER BY score desc) as 'Rank' 
FROM rank;

结果:

+------+---------+
| score|   Rank  |
+------+---------+
|  100 |       1 |
|  100 |       1 |
|  95  |       2 |
|  95  |       2 |
|  95  |       2 |
|  90  |       3 |
|  89  |       4 |
+------+---------+
7 rows in set (0.02 sec)

若按照某个字段分区进行排序的话,例如按照name进行分区,根据分数进行排名

SELECT name , 
	score ,
	dense_rank() over(partition by name ORDER BY score desc) as 'Rank' 
	FROM rank;

首先,PARTITION BY子句按姓名将结果集分成多个分区。

然后,ORDER BY子句按分数对结果集进行排名。

结果:

+------+------+---------+
| name | score|   Rank  |
+------+------+---------+
|  a   |  100 |       1 |
|  a   |  90  |       2 |
|  a   |  89  |       3 |
|  b   |  100 |       1 |
|  c   |  95  |       1 |
|  d   |  95  |       1 |
|  e   |  95  |       1 |
+------+------+---------+
7 rows in set (0.02 sec)

这数据可能不太明显,如果再插入一条数据:

insert into rank values(8,'a',90);

然后查询,结果如下,与rank函数执行的结果就可以看到区别了:

+------+------+---------+
| name | score|   Rank  |
+------+------+---------+
|  a   |  100 |       1 |
|  a   |  90  |       2 |
|  a   |  90  |       2 |
|  a   |  89  |       3 |
|  b   |  100 |       1 |
|  c   |  95  |       1 |
|  d   |  95  |       1 |
|  e   |  95  |       1 |
+------+------+---------+
7 rows in set (0.02 sec)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解MySQL 数据分组

    详解MySQL 数据分组

    这篇文章主要介绍了MySQL 数据分组的相关资料,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下
    2020-12-12
  • MySQL表内连和外连的具体使用

    MySQL表内连和外连的具体使用

    我们在使用MySQL的时候,经常涉及到内连接和外连接的应用,本文就来详细的介绍一下MySQL表内连和外连的具体使用,感兴趣的可以了解一下
    2023-10-10
  • 基于更新SQL语句理解MySQL锁定详解

    基于更新SQL语句理解MySQL锁定详解

    这篇文章主要给大家介绍了关于MySQL数据库SQL更新锁定的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 将MySQL的临时目录建立在内存中的教程

    将MySQL的临时目录建立在内存中的教程

    这篇文章主要介绍了将MySQL的临时目录建立在内存中的教程,以获得不关机情况下的高性能使用,需要的朋友可以参考下
    2015-04-04
  • Mysql导入导出工具Mysqldump和Source命令用法详解

    Mysql导入导出工具Mysqldump和Source命令用法详解

    Mysql本身提供了命令行导出工具Mysqldump和Mysql Source导入命令进行SQL数据导入导出工作,通过Mysql命令行导出工具Mysqldump命令能够将Mysql数据导出为文本格式(txt)的SQL文件,通过Mysql Source命令能够将SQL文件导入Mysql数据库中,下面通过Mysql导入导出SQL实例详解Mysqldump和Source命令的用法
    2012-09-09
  • 解决mySQL中1862(phpmyadmin)/1820(mysql)错误的方法

    解决mySQL中1862(phpmyadmin)/1820(mysql)错误的方法

    最近在工作中发现一直在运行的mysql突然报错了,错误提示1820,phpmyadmin也不能登陆,错误为1862,虽然摸不着头脑但只能想办法解决,下面这篇文章给大家分享了解决这个问题的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • 什么是分表和分区 MySql数据库分区和分表方法

    什么是分表和分区 MySql数据库分区和分表方法

    这篇文章主要为大家详细介绍了MySql数据库分区和分表方法,告诉大家什么是分表和分区,mysql分表和分区有什么联系,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • CentOS 7安装MySQL的详细步骤

    CentOS 7安装MySQL的详细步骤

    这篇文章主要为大家介绍了CentOS 7安装MySQL的详细步骤,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • MySQL高效可靠处理持久化数据的教程指南

    MySQL高效可靠处理持久化数据的教程指南

    这篇文章主要给大家详细介绍了 MySQL 如何高效可靠处理持久化数据,文中有详细的流程步骤和代码示例,对我们的学习有一定的帮助,需要的朋友可以参考下
    2023-07-07
  • mysql根据拼音字母查询(简单易懂的字段拼音查询)

    mysql根据拼音字母查询(简单易懂的字段拼音查询)

    MySQL在开发中,我们经常需要根据字段拼音查询数据库中的数据,它支持多种查询方式,包括根据拼音字母查询,使用 Collation 可以方便地进行简单的拼音查询,而使用拼音索引可以大幅提高查询性能,根据具体的需求和情况,我们可以选择合适的方法来实现拼音查询
    2023-10-10

最新评论