摘要

本文对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()的区别的更多相关文章

  1. SQL Server排序函数row_number和rank的区别

    SQL Server排序函数row_number和rank的区别 直接看测试结果 declare @table table(name varchar(100),amount int, memo var ...

  2. MySQL 下 ROW_NUMBER / DENSE_RANK / RANK 的实现

    原文链接:http://hi.baidu.com/wangzhiqing999/item/7ca215d8ec9823ee785daa2b MySQL 下 ROW_NUMBER / DENSE_RAN ...

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

    row_number的用途非常广泛,排序最好用它,它会为查询出来的每一行记录生成一个序号,依次排序且不会重复,注意使用row_number函数时必须要用over子句选择对某一列进行排序才能生成序号. ...

  4. oracle中row_number和rownum的区别和联系(翻译)

    http://www.tuicool.com/articles/bI3IBv 附问题:有以下一个SQL语句: SELECT * FROM ( SELECT t.*, row_number() OVER ...

  5. mysql分组排序取最大值所在行,类似hive中row_number() over partition by

    如下图, 计划实现 :按照 parent_code 分组, 取组中code最大值所在的整条记录,如红色部分.(类似hive中: row_number() over(partition by)) sel ...

  6. Oracle中row_number()、rank()、dense_rank() 的区别

    link:https://www.cnblogs.com/qiuting/p/7880500.html

  7. hive内group by取第一条数据,Hive中row_number的使用

    1.hive的分组和组内排序---语法 语法: row_number() over (partition by 字段a order by 计算项b desc ) rank rank是排序的别名 par ...

  8. Hive中变量的使用

    1.Hive配置属性 (1)命令行方式 Hive配置属性存储于 hiveconf 命名空间中,该命名空间中的属性是可读写的.在查询语句中插入 '${hiveconf:变量名}',就可以通过 hive ...

  9. hive 中窗口函数row_number,rank,dense_ran,ntile分析函数的用法

    hive中一般取top n时,row_number(),rank,dense_ran()这三个函数就派上用场了, 先简单说下这三函数都是排名的,不过呢还有点细微的区别. 通过代码运行结果一看就明白了. ...

随机推荐

  1. xshell密钥登录服务器

    其实很简单 1 xshell 生成pub key . 在工具 -> 用户密钥管理. 生成 .另存为id_rsa_1024.pub 2.服务器上ssh-keygen 3.将生成的文件id_rsa_ ...

  2. react-debug

    最近练习react的时候遇到一些问题: 在redux模式下,同一个api依据参数获取不同data的时候,返回的data相同 原因:多次调用该接口时,action的type相同,导致对应于该接口的每个r ...

  3. node的http模块

    node中的几个常用核心模块的api返回的都是eventEmitter的实例,也就是说都继承了on和emit方法,用以监听事件并触发回调来处理事件. http模块处理网络请求通常是创建一个server ...

  4. React面试题汇总

    1.如何理解React中的组件间数据传递? ①父-子  通过props传递 ②子-父  在父中创建一个可以修改state的方法,之后把这个方法通过props传递给子,在子中调用这个方法 从而达到修改父 ...

  5. zabbix监控redis多实例cpu mem-自动发现

    1.自动发现实例端口脚本,用于zbx item prototypes #!/bin/bash REDIS_PORT=`ps aux |grep redis-server | grep -v 'grep ...

  6. mysql小白系列_08 zabbix3.2.6概念及部署

    一 zabbix功能简介 1.zabbix三大监控组件 zabbix server web gui database zabbix_server zabbix proxy agent client 2 ...

  7. Palindromes _easy version(hdu2029)

    输入格式:首先一个整型,然后循环不带空格未知长度的字符串. 思考:首先用scanf_s()输入整型,然后一个大循环,用gets_s()函数输入字符串. 注意:scanf_s()多加了一个%c,& ...

  8. Centos 安装 Anaconda

    # 首先从 Anaconda 官网下载 anaconda Linux 64Bit 版本命令行安装包 $ wget https://repo.continuum.io/archive/Anaconda3 ...

  9. SEPC:使用3D卷积从FPN中提取尺度不变特征,涨点神器 | CVPR 2020

    论文提出PConv为对特征金字塔进行3D卷积,配合特定的iBN进行正则化,能够有效地融合尺度间的内在关系,另外,论文提出SEPC,使用可变形卷积来适应实际特征间对应的不规律性,保持尺度均衡.PConv ...

  10. 02.Django-模板

    模板 1. 简介 模板由HTML代码和逻辑控制代码构成 同一个模板,可以有多个上下文,就可以通过穿件模板对象来渲染多个上下文 创建一个模板就可以多次调用render()方法来渲染上下文 Django模 ...