推广 热搜:   公司  企业  中国  快速    行业  上海  设备  未来 

数据库中row_number() 分组排序函数的具体使用

   日期:2024-12-29     移动:http://fabua.ksxb.net/mobile/quote/5096.html

‌row_number() over (partition by order by) 是一种‌SQL窗口函数,在Oracle、Hive 以及mysql8.0以上版本可以使用,用于在每个分区内对每一行进行排序并编号,。它一般用于分析和报表等场景,可以帮助我们对数据进行分区后排序,获取排名信息。

row_number() 函数搭配partition by与order by函数可以完成以下功能。

  • 对查询结果集中的每一行分配一个唯一的数字,从1开始编号。
  • 结合partition by可以先对结果进行分组,然后组内每条数据再从1开始编号。

应用场景:比如学校考试结束后,按科目进行分组,每个科目按成绩进行排序,获取前十名。

总结:row_numer是一个分组排序函数,可以对查询结果集先进行分组,然后每组内再进行排序。对每个分组内的每行分配一个从1开始的连续唯一编号。

注意:以下两种写法都是分组排序函数,语法达到的效果是一致的。

  • ROW_NUMBER() OVER (partition by order by)在Oracle、Hive 以及mysql8.0以上版本可以使用。
  • ROW_NUMBER() OVER (distribute by sort by)在,hive支持。

第一种写法:row_number() over (partition by 分组列 order by 排序列 asc/desc) as 别名

第二种写法:row_number() over(distribute by 分组列 sort by 排序列 asc/desc) as 别名

简单来说就是函数执行时首先会根据partition by的列来进行分组,分完组后在每个分组内再根据order by 的列来进行排序。

‌功能‌:

  • ROW_NUMBER() 函数。
  • 分组是通过 PARTITION BY 子句实现的,它指定了分组的依据。
  • 排序是通过 ORDER BY 子句实现的,它指定了行号分配的顺序。

注意:

  • over()中可以只有partition by,也可以只有order by。
  • partition by后面跟的分组列可以有多个,order by后面跟的排序列也可以有多个。

问题

Q:row_number函数为每个分组内的每一行分配一个唯一的连续编。即分组内的每行数据编号只会从1开始分配并且不重复。假如我们是对考试分数进行排序,希望分数相同的人排名一样该怎么办呢?
A:这时候就要使用到RANK()函数或者DENSE_RANK()函数了。这两个函数会对相同的值分配相同的排名。具体请参考《row_number()、rank() 和 dense_rank() 的区别、分组排序函数》、《数据库rank()分组排序函数详解》、《数据库dense_rank() 函数的使用、MySQL之dense_rank()、Hive之dense_rank()函数》

以下示例基于mysql8.0进行执行

准备数据

表数据:

注:如果不指定分组那么会对全局进行排序,将所有数据视为一组; 然后每组内对每一行从1开始进行连续编号。如上图rn从1开始编号到9。

注:先执行PARTITION BY按name分组,然后ORDER BY在分组内按照salary排序。
如上图:RN会对每组内的每行数据分配一个唯一的连续编号。

也就是分组后按薪资排序,并找出每个分组内薪资最高(排序为1)的记录

查到每个id的最高薪资,即每个id分组内排名为1的

举一反三:我们也可以通过上述这个示例,比如。即先进行分组,然后对分数进行排序后获取RN<=10的。

注意: 在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、
order by 的执行。

partition by 用于给结果集分组,如果没有指定分组列那么它把整个结果集作为一个分组,它和聚合函数不同的地方在于它能够返回一个分组中的多条记录,而聚合函数一般只有一个反映统计值的记录。

partition by可以根据多个字段进行分组、order by也可以根据多个字段排序。

假如我们在对表执行insert的时候,不小心多执行了几次,如何利用row_number对数据进行去重呢?

数据准备

重复数据如下:

如上图,每条数据都重复插入了3次,那么该如何去重呢?

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

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

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

具体请参考《row_number()、rank() 和 dense_rank() 的区别、分组排序函数》、《数据库rank()分组排序函数详解》、《数据库dense_rank() 函数的使用、MySQL之dense_rank()、Hive之dense_rank()函数》

本文地址:http://fabua.ksxb.net/quote/5096.html    海之东岸资讯 http://fabua.ksxb.net/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


相关最新动态
推荐最新动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号