第八周 第5章 Hive高级函数实战
函数的基本操作
1 | 和mysql一样的,hive也是一个主要做统计的工具,所以为了满足各种各样的统计需要,他也内置了相当多的函数,我们可以通过 show functions; 来查看hive中的内置函数 |
1 | 查看指定函数的描述信息我们可以使用: desc function functionName; |
1 | 显示函数的扩展内容 |
Hive高级函数应用
1 | 普通的就不说了,mysql中支持的函数这里面大部分都支持,并且hive支持的函数比mysql还要多,在这里我们主要挑几个典型的说一下 |
分组排序取TopN
1 | 一个典型的应用场景,分组排序取TopN操作 |
1 | 我们的需求是这样,有一份学生的考试分数信息,语文、数学、英语这三门,需要计算出班级中单科排名前三名学生的姓名 |
1 | 建表 |
1 | 加载数据 |
row_number()
1 | 我们先使用row_number对数据编号,看一下是什么样子,row_number不能单独使用,在这里需要加上over |

1 | 结果如下:在这里相当于给表里面的所有数据编了一个号,从1开始 |
1 | 执行sql |
1 | 接着就可以获取前三名了, |

rank()
1 | 前面SQL中的 row_number() 可以替换为 rank() 或者 dense_rank() |

dense_rank()
1 | dense_rank() 表示上下两条记录的score相等时,下一个score值的行号递增1,比如:有两条并列第一,下一个是第二 |
总结
1 | row_number() over() 是正常排序 |
行转列
1 | 行转列就是把多行数据转为一列数据 |
CONCAT_WS()
1 | hive (default)> desc function CONCAT_WS; |
1 | CONCAT_WS() 函数可以实现根据指定的分隔符拼接多个字段的值,最终转化为一个带有分隔符的字符串 |
COLLECT_LIST()
1 | hive (default)> desc function COLLECT_LIST; |
COLLECT_SET()
1 | hive (default)> desc function COLLECT_SET; |
实现
1 | [root@bigdata04 hivedata]# more student_favors.data |
1 | 开始对原始数据建表 |
1 | 查看数据 |
1 | 先对name字段进行分组,把favor转成一个数组 |
1 | 结果如下 |
1 | 然后再使用 concat_ws 把数组中的元素按照指定分隔符转成字符串 |
1 | 结果如下 |
1 | 我们发现这里面有一些爱好是重复的,如果不希望出现重复的话可以使用COLLECT_SET() |
列转行
1 | 列转行是和刚才的行转列反着来的,列转行可以把一列数据转成多行 |
SPLIT()
1 | hive (default)> desc function SPLIT; |
EXPLODE()
1 | hive (default)> desc function EXPLODE; |
LATERAL VIEW
1 | Lateral view通常和split,explode等函数一起使用。 |
实现
1 | [root@bigdata04 hivedata]# more student_favors_2.data |
1 | 希望的结果是这样的 |
1 | 接着建表 |
1 | 上传数据 |
1 | 先使用split对favorlist字段进行切割 |
1 | 再使用explode对数据进行操作 |
1 | 其实到这里已经实现了列转行了,但是还需要把name字段拼接上,这时候就需要使用later view了,否则直接查询name字段会报错 |
1 | select name,favor_new from student_favors_2 lateral view explode(split(favorlist,',')) table1 as favor_new; |
1 | 结果如下: |
Hive排序相关函数
ORDER BY
1 | Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排序,使用这个语句的时候生成的reduce任务只有一个 |
SORT BY
1 | Hive中指定了sort by,如果有多个reduce,那么在每个reducer端都会做排序,也就是说保证了局部有序(每个reducer出来的数据是有序的,但是不能保证所有的数据是全局有序的,除非只有一个reducer) |
1 | 执行排序SQL |
1 | 刚才我们说sort by是局部有序,为什么最终的结果还是全局有序呢? |
1 | 此时会发现数据就没有全局排序了,因为有多个reduce了。 |
DISTRIBUTE BY
1 | ditribute by是控制map的输出到reducer是如何划分的 |
1 | hive (default)> set mapreduce.job.reduces = 2; |
1 | 可以结合sort by实现分区内的排序,默认是升序,可以通过desc来设置倒序 |
1 | hive (default)> select id from t2_bak distribute by id sort by id desc; |
CLUSTER BY
1 | cluster by的功能就是distribute by和sort by的简写形式 |
Hive 的分组和去重函数
1 | GROUP BY :对数据按照指定字段进行分组 |
1 | 第一种:使用distinct会将所有的name都shuffle到一个reducer里面,性能较低 |