Hive中row_number()、dense_rank()、rank()的区别
摘要
本文对Hive中常用的三个排序函数row_number()、dense_rank()、rank()的特性进行类比和总结,并通过笔者亲自动手写的一个小实验,直观展现这三个函数的特点。
三个排序函数的共同点与区别
| 函数 | 共同点 | 不同点 |
| row_number() | 用于特定场景下实现排序需求; 均从1开始排序 |
无重复排名(相同排名的按序排名) |
| dense_rank() | 有相同排名,但不会跳过占用的排名 | |
| rank() | 有相同排名,但会跳过占用的排名 |
实验示例
set mapreduce.job.queuename=QueueA;
use STUDENT_DB;
--创建学生分数表
DROP TABLE IF EXISTS STUDENT_DB.SCORE_TABLE1;
CREATE TABLE IF NOT EXISTS STUDENT_DB.SCORE_TABLE1
(
ID STRING COMMENT '唯一ID',
NAME STRING COMMENT '姓名',
SCORE INT COMMENT '分数',
CLASS_NUM STRING COMMENT '班级编号'
)
COMMENT '学生分数表'
PARTITIONED BY (pt_dt STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\27'
STORED AS ORCFILE;
--向学生分数表插入数据
INSERT OVERWRITE TABLE STUDENT_DB.SCORE_TABLE1 PARTITION(pt_dt='2019-12-12') VALUES
('1', '小明', 89, '1班'),
('2', '小红', 90, '1班'),
('3', '小军', 90, '1班'),
('4', '小胖', 91, '1班'),
('5', '小李', 87, '1班'),
('6', '小郭', 99, '1班');
--创建学生分数排序结果表
DROP TABLE IF EXISTS STUDENT_DB.SCORE_RANK_TABLE1;
CREATE TABLE IF NOT EXISTS STUDENT_DB.SCORE_RANK_TABLE1
(
ID STRING COMMENT '唯一ID',
NAME STRING COMMENT '姓名',
SCORE INT COMMENT '分数',
CLASS_NUM STRING COMMENT '班级编号',
ROW_NUMBERS STRING COMMENT 'ROW_NUMBER排序结果',
DENSE_RANKS STRING COMMENT 'DENSE_RANKS排序结果',
RANKS STRING COMMENT 'RANKS排序结果'
)
COMMENT '学生分数排序结果表'
PARTITIONED BY (pt_dt STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\27'
STORED AS ORCFILE;
INSERT OVERWRITE TABLE STUDENT_DB.SCORE_RANK_TABLE1 PARTITION(pt_dt='2019-12-12')
SELECT ID,
NAME,
SCORE,
CLASS_NUM,
ROW_NUMBER() OVER(PARTITION BY CLASS_NUM ORDER BY SCORE DESC) AS ROW_NUMBERS,
DENSE_RANK() OVER(PARTITION BY CLASS_NUM ORDER BY SCORE DESC) AS DENSE_RANKS,
RANK() OVER(PARTITION BY CLASS_NUM ORDER BY SCORE DESC) AS RANKS
FROM STUDENT_DB.SCORE_RANK_TABLE1
WHERE pt_dt='2019-12-12';
SELECT ID,
NAME,
SCORE,
CLASS_NUM,
ROW_NUMBERS,
DENSE_RANKS,
RANKS,
pt_dt
FROM STUDENT_DB.SCORE_RANK_TABLE1
WHERE pt_dt='2019-12-12';
实验结果
SCORE_RANK_TABLE1
| ID | NAME | SCORE | CLASS_NUM | ROW_NUMBERS | DENSE_RANKS | RANKS | pt_dtpt_dt |
|---|---|---|---|---|---|---|---|
| 6 | 小郭 | 99 | 1班 | 1 | 1 | 1 | 2019-12-12 |
| 4 | 小胖 | 91 | 1班 | 2 | 2 | 2 | 2019-12-12 |
| 3 | 小军 | 90 | 1班 | 3 | 3 | 3 | 2019-12-12 |
| 2 | 小红 | 90 | 1班 | 4 | 3 | 3 | 2019-12-12 |
| 1 | 小明 | 89 | 1班 | 5 | 4 | 5 | 2019-12-12 |
| 5 | 小李 | 87 | 1班 | 6 | 5 | 6 | 2019-12-12 |
如上表所示,1班的小军和小红分数均为90,当我们使用ROW_NUMBERS()进行排序时,他们的排名不会并列,而是分别有一个排名。
当我们使用DENSE_RANK()进行排序时,他们的排名会并列,且后续记录的排名会以当前并列排名为基础+1,即不会跳过被占用的位置。
当我们使用RANK()进行排名时,他们的排名会并列,且后续记录的排名会跳过被占用的排名数,而不会顺延下去。
总结
在实际开发过程中,可根据场景的需要去选择具体的排序函数。一个较为常见的场景是根据某个字段partition by之后在该范围内order by进行排序,然后取首条记录,这时候row_number()基本可以满足需求。
除此之外,排序函数均较耗性能,特别是如果对大数据量进行全局排序时,一定要考虑性能问题,非必要情况下,避免对大数据量进行全局排序。
Hive中row_number()、dense_rank()、rank()的区别的更多相关文章
- SQL Server排序函数row_number和rank的区别
SQL Server排序函数row_number和rank的区别 直接看测试结果 declare @table table(name varchar(100),amount int, memo var ...
- MySQL 下 ROW_NUMBER / DENSE_RANK / RANK 的实现
原文链接:http://hi.baidu.com/wangzhiqing999/item/7ca215d8ec9823ee785daa2b MySQL 下 ROW_NUMBER / DENSE_RAN ...
- 数据库中row_number()、rank()、dense_rank() 的区别
row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号. ...
- oracle中row_number和rownum的区别和联系(翻译)
http://www.tuicool.com/articles/bI3IBv 附问题:有以下一个SQL语句: SELECT * FROM ( SELECT t.*, row_number() OVER ...
- mysql分组排序取最大值所在行,类似hive中row_number() over partition by
如下图, 计划实现 :按照 parent_code 分组, 取组中code最大值所在的整条记录,如红色部分.(类似hive中: row_number() over(partition by)) sel ...
- Oracle中row_number()、rank()、dense_rank() 的区别
link:https://www.cnblogs.com/qiuting/p/7880500.html
- hive内group by取第一条数据,Hive中row_number的使用
1.hive的分组和组内排序---语法 语法: row_number() over (partition by 字段a order by 计算项b desc ) rank rank是排序的别名 par ...
- Hive中变量的使用
1.Hive配置属性 (1)命令行方式 Hive配置属性存储于 hiveconf 命名空间中,该命名空间中的属性是可读写的.在查询语句中插入 '${hiveconf:变量名}',就可以通过 hive ...
- hive 中窗口函数row_number,rank,dense_ran,ntile分析函数的用法
hive中一般取top n时,row_number(),rank,dense_ran()这三个函数就派上用场了, 先简单说下这三函数都是排名的,不过呢还有点细微的区别. 通过代码运行结果一看就明白了. ...
随机推荐
- 【Django+Element UI】使用一个接口文件,搞定分页获取数据,模糊查询后分页获取数据
1:序列化获取数据的接口设计 1:分页获取序列化数据 2:是个能传参数的接口 class Society(APIView): def post(self, request): keywords = s ...
- python操作rabbitmq,实现生产消费者模型
更多详情参考官方文档:https://www.rabbitmq.com/tutorials/tutorial-six-python.html 参考博客:https://blog.csdn.net/we ...
- HTTP响应格式
HTTP响应格式
- codis原理及部署_01
一.codis介绍 Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到Codis Proxy和连接原生的RedisServer没有明显的区别,有部分命令不支持 Codis底层会处理请 ...
- SQL拦截器
一.拦截SQL 1.slow log 2.general log 3.mycat sql拦截器 二.mycat sql拦截器 1.配置server.xml # 1.5可用 <system> ...
- 一言难尽,Jpa这个功能差点让我丢了工作
故事背景 前阵子,有位朋友在微信上问我数据被删了能不能恢复,我问了下原因,居然是因为一个配置项惹的祸. 故事细节 在 Spring Boot 中使用 jpa 来操作数据库,jpa 就不做详细的介绍了, ...
- elasticsearch7.X x-pack破解
简介: x-pack是elasticsearch的一个收费的扩展包,将权限管理,警告,监视等功能捆绑在一个易于安装的软件包中,x-pack被设计为一个无缝的工作,但是你可以轻松的启用或者关闭一些功能. ...
- Linux下db2V10.5命令行安装超详细图文教程(附下载地址)
下载地址:https://pan.baidu.com/s/1GtF03x1FMF3IsGdSiBJu-g 提取码:8vfj 失效了发邮件:wells974@163.com 一.db2prereqche ...
- 认证(Authentication)和授权(Authorization)总结
身份认证是验证你的身份,一旦通过验证,即启用授权.你所拥有的身份可以进行哪些操作都是由授权规定.例如,任何银行客户都可以创建一个账户(如用户名),并使用该账户登录该银行的网上服务,但银行的授权政策必须 ...
- Rocket - jtag - JtagStateMachine
https://mp.weixin.qq.com/s/cFXVOBHayV2w27jpT5RglA 简单介绍JtagStateMachine的实现. 1. 简单介绍 根据IEEE 1149.1-200 ...