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()这三个函数就派上用场了, 先简单说下这三函数都是排名的,不过呢还有点细微的区别. 通过代码运行结果一看就明白了. ...
随机推荐
- NullPointerException异常没有异常栈打印问题追踪
今天去服务器后台看日志,发现有很多NullPointerException异常.我下意识的找异常栈,想看下到底是哪行代码导致了空指针.但是发现日志中只打印出了如下日志: null java.lang. ...
- 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!
写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*) ,那什么是Stream API呢?Java8中的 ...
- Centos 安装 docker 和 docker-compose
一.docker安装 1.卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ d ...
- 【面经分享】互联网寒冬,7面阿里,终获Offer,定级P6+
点赞再看,养成习惯,微信搜索[敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文 ...
- css不换行解决
word-wrap: break-word; word-break: break-all; white-space: pre-wrap;
- EL表达式用法---查询博客
jsp脚本:<%=request.getAttribute(name)%>EL表达式替代上面的脚本:${requestScope.name} 使用EL最主要的作用是获得四大域中的数据,格式 ...
- 0418部分HomeWork案例
/* 月份 输入月份,对应返回该月份的天数 利用switch的穿透性,可将多个case合到一个代码块 */ import java.util.Scanner; class HomeWork5{ pub ...
- JavaScript之倔强的字符串
关于倔强的JavaScript字符串:不可以被修改 我们是字符串 我们的口号是:你可以消灭我,但是你不能改变我 JavaScript字符串是不可改变的,当真是这样的吗? 让我们来试验一下. var n ...
- MFC---编辑框控件
1.编辑框内允许多行输入,或者说是允许敲回车 编辑框属性里将multiline设置为TRUE或者将Want Return设置为TRUE 2.水平滚动条,垂直滚动条 Horizontal Scroll ...
- PAT1080 MOOC期终成绩 (25分) ——同样参考了柳婼大神的代码及思路,在自己的代码上做了修改,还是很复杂
1080 MOOC期终成绩 (25分) 对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分 ...