数据库中row_number()、rank() 和 dense_rank() 的区别

 更新时间:2024年11月18日 11:33:16   作者:五月天的尾巴  
本文主要结合了SQL中的排名函数ROW_NUMBER()、RANK()和DENSE_RANK(),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在数据分析和处理的过程中,尤其是在使用 SQL 进行查询时,排名函数(Ranking Functions)是一个非常重要的工具。Apache Hive 和其他数据库系统都提供了一些排名函数,常见的包括 ROW_NUMBER()、RANK() 和 DENSE_RANK()。虽然这三个函数都可以用于为结果集中的行分配一个排名,但它们的工作原理和返回结果却各不相同。本文将深入探讨这三个函数的区别、使用场景以及实例演示。

ROW_NUMBER()、RANK() 和 DENSE_RANK()是排名函数,也叫分组排序函数。即可以对查询结果集进行分组后进行排序,对结果集的每一行分配一个编号。例如:对考试成绩按科目进行分组,然后按分数排序,获取前5名。

ROW_NUMBER()、RANK() 和 DENSE_RANK()这三个函数在mysql8.0、hive、oracle都是支持的

一、函数定义

1.1、ROW_NUMBER()

ROW_NUMBER() 函数用于为结果集中的每一行分配一个唯一的序号。无论是否存在重复值,ROW_NUMBER() 返回的序号都是连续的。这个函数常用于需要唯一行号的场景。

基本语法:

ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2)
  • PARTITION BY:指定如何将结果集分组。
  • ORDER BY:指定每个分组内的排序规则。

1.2、RANK()

RANK() 函数与 ROW_NUMBER() 类似,也用于对结果集中的行进行排名,但在处理重复值时表现不同。RANK() 会为相同的值分配相同的排名,并在随后排名中跳过相应的名次

基本语法:

RANK() OVER (PARTITION BY column1 ORDER BY column2)

1.3、DENSE_RANK()

DENSE_RANK() 函数也是用于排名的,其与 RANK() 的主要区别在于处理重复值时的行为。DENSE_RANK() 为相同的值分配相同的排名,但不会跳过名次

基本语法:

DENSE_RANK() OVER (PARTITION BY column1 ORDER BY column2)

1.4、row_number()、rank() 和 dense_rank() 的区别

  • ROW_NUMBER():为每一行分配一个唯一的行号。即使有重复值,返回的行号也是唯一且连续的。
  • RANK():为相同的值分配相同的排名,但在后续排名中会跳过相应的名次。例如,如果有两个并列第一的记录,则下一个记录的排名为第三。
  • DENSE_RANK():与 RANK() 类似,给相同的值分配相同的排名,但后续排名不会跳过。相同的值后面的排名是紧接着的下一个值。

二、使用示例

结合示例来看一下三者之间的区别,以下sql基于MySql8.0进行讲解。

建表语句:

create table test(
       id varchar(10) NOT NULL,
       `name` varchar(10) NULL,
       age varchar(10) NULL,
       salary int NULL
);
-- 数据是每个人不同年龄段的薪资数据
insert into test(id,`name`,age,salary) values(1,'张三',24,15000);
insert into test(id,`name`,age,salary) values(2,'李四',22,8000);
insert into test(id,`name`,age,salary) values(3,'王五',20,6500);
insert into test(id,`name`,age,salary) values(4,'赵六',23,15000);
insert into test(id,`name`,age,salary) values(5,'孙七',22,8000);
insert into test(id,`name`,age,salary) values(6,'周八',21,7500);

表数据:

在这里插入图片描述

以下是使用这三个函数的 SQL 查询示例:

SELECT id, name, salary,
       ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn,
       RANK() OVER (ORDER BY salary DESC) AS `rank`,
       DENSE_RANK() OVER (ORDER BY salary DESC) AS `dense_rank`
FROM test;

在这里插入图片描述

注意:以上sql只使用了order by进行排序,并没有使用partition by进行分组,所以默认是同一组,然后组内进行排名。

从上表可以看出:

  • ROW_NUMBER(): 会为每一行数据分配唯一连续的编号,不会因为排名相同而分配相同的编号。
  • RANK(): 若排名相同则分配相同的编号,并在随后排名中跳过相应的名次。
  • DENSE_RANK(): 若排名相同则分配相同的编号,并在随后排名中不跳过相应的名次。

三、总结

在数据分析中,ROW_NUMBER()、RANK() 和 DENSE_RANK() 是非常有用的工具。它们可以帮助用户快速对数据进行排名和分类分析。虽然这三种函数的作用相似,但因其在处理重复值时的行为不同,所以在使用时需要根据具体需求进行选择。

3.1、row_number()、rank() 和 dense_rank() 的区别

  • ROW_NUMBER():为每一行分配唯一的行号,适合唯一标识需求。
  • RANK():为重复值分配相同的排名,并在后续排名中跳过名次,适合需要处理排名的场景。
  • DENSE_RANK():为重复值分配相同的排名,但不跳过名次,适合希望连续排名的场景。

下面表格总结了这三个函数的主要区别:

函数特点排名示例
ROW_NUMBER为每行分配唯一的数字1, 2, 3, 4, …
RANK相同的值共享相同的排名,排名会跳过数字1, 1, 3, 4, …
DENSE_RANK相同的值共享相同的排名,不跳过数字1, 1, 2, 3, …

具体请参考《row_number() over (partition by 分组列 order by 排序列 desc)、row_number() 函数、分组排序函数》、《数据库rank()分组排序函数详解》、《数据库dense_rank() 函数的使用、MySQL之dense_rank()、Hive之dense_rank()函数

到此这篇关于数据库中row_number()、rank() 和 dense_rank() 的区别的文章就介绍到这了,更多相关row_number() rank()  dense_rank()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 读取mysql一个库下面的所有的表table

    读取mysql一个库下面的所有的表table

    本文给大家分享的是如何使用php实现读取mysql一个库下面的所有的表table的代码,有需要的小伙伴可以参考下
    2016-12-12
  • Mysql 5.7.19 免安装版遇到的坑(收藏)

    Mysql 5.7.19 免安装版遇到的坑(收藏)

    这篇文章给大家分享了mysql 5.7.19免安装版在安装过程中遇到的一些问题,以前有mysql服务的话 需要去停掉mysql服务。具体内容介绍大家参考下本文
    2017-08-08
  • MySQL中报错:Can’t find file: ‘./mysql/plugin.frm’的解决方法

    MySQL中报错:Can’t find file: ‘./mysql/plugin.frm’的解决方法

    这篇文章主要给大家介绍了关于在MySQL中报错:Can't find file: './mysql/plugin.frm'的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • MySQL高效可靠处理持久化数据的教程指南

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

    这篇文章主要给大家详细介绍了 MySQL 如何高效可靠处理持久化数据,文中有详细的流程步骤和代码示例,对我们的学习有一定的帮助,需要的朋友可以参考下
    2023-07-07
  • mysql中的limit和offset用法详解

    mysql中的limit和offset用法详解

    这篇文章主要介绍了mysql中的limit和offset用法详解,limit一般被用来排序,offset一般和limit组合使用,本文对这两个函数进行详细介绍,需要的朋友可以参考下
    2023-10-10
  • CMS不要让MySQL为你流泪

    CMS不要让MySQL为你流泪

    MySQL是中小型网站普遍使用的数据库之一,然而,很多人并不清楚MySQL到底能支持多大的数据量,再加上某些国内CMS厂商把数据承载量的责任推给它,导致很多不了解MySQL的站长对它产生了很多误解
    2008-12-12
  • mysql如何查询表中的字段数量

    mysql如何查询表中的字段数量

    这篇文章主要介绍了mysql如何查询表中的字段数量问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 详解MySQL 重做日志(redo log)与回滚日志(undo logo)

    详解MySQL 重做日志(redo log)与回滚日志(undo logo)

    这篇文章主要介绍了MySQL redo与undo日志的相关资料,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下
    2020-08-08
  • mysql缺少my.ini文件的最佳解决方法

    mysql缺少my.ini文件的最佳解决方法

    my.ini是MySQL数据库中使用的配置文件,修改这个文件可以达到更新配置的目的,下面这篇文章主要给大家介绍了关于mysql缺少my.ini文件的最佳解决方法,需要的朋友可以参考下
    2024-01-01
  • MySQL中替代Like模糊查询的函数方式

    MySQL中替代Like模糊查询的函数方式

    这篇文章主要介绍了MySQL中替代Like模糊查询的函数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08

最新评论