「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战」。
一、函数
1、系统内置函数
1.1、查看系统自带的函数
1 | hive复制代码hive (default)> show functions; |
1.2、显示自带的函数的用法
1 | hive复制代码hive (default)> desc function upper; |
1.3、详细显示自带的函数的用法
1 | hive复制代码hive (default)> desc function extended upper; |
2、常用内置函数
2.1、空字段赋值
- 函数说明
NVL:给值为 NULL 的数据赋值,它的格式是 NVL( value,default_value)。它的功能是如果 value 为 NULL,则 NVL 函数返回 default_value 的值,否则返回 value 的值,如果两个参数都为 NULL ,则返回 NULL。
- 数据准备:采用员工表
- 查询:如果员工的 comm 为 NULL,则用-1 代替
1 | hive复制代码hive (default)> select comm,nvl(comm,-1) from emp; |
- 查询:如果员工的 comm 为 NULL,则用领导 id 代替
1 | hive复制代码hive (default)> select comm,nvl(comm,mgr) from emp; |
2.2、CASE WHEN THEN ELSE END
- 数据准备
2. 需求
求出不同部门男女各多少人。结果如下:
3. 创建本地 emp_sex.txt,导入数据
1 | shell复制代码[moe@hadoop102 datas]$ vi emp_sex.txt |
- 创建 hive 表并导入数据
1 | hive复制代码hive (default)> create table emp_sex |
- 按需求查询数据
1 | hive复制代码hive (default)> select |
2.3、行转列
- 相关函数说明
CONCAT(string A/col, string B/col…):返回输入字符串连接后的结果,支持任意个输入字符串;
CONCAT_WS(separator, str1, str2,…):它是一个特殊形式的 CONCAT()。第一个参数剩余参数间的分隔符。分隔符可以是与剩余参数一样的字符串。如果分隔符是 NULL,返回值也将为 NULL。这个函数会跳过分隔符参数后的任何 NULL 和空字符串。分隔符将被加到被连接的字符串之间;
注意: CONCAT_WS must be "string or array<string>
COLLECT_SET(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生 Array 类型字段。
2. 数据准备
3. 需求
把星座和血型一样的人归类到一起。结果如下:
4. 创建本地 constellation.txt,导入数据
创建本地 constellation.txt,导入数据
1 | shell复制代码[moe@hadoop102 datas]$ vim person_info.txt |
- 创建 hive 表并导入数据
1 | hive复制代码hive (default)> create table person_info |
- 按需求查询数据
1 | hive复制代码hive (default)> SELECT |
2.4、列转行
- 函数说明
EXPLODE(col):将 hive 一列中复杂的 Array 或者 Map 结构拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解释:用于和 split, explode 等 UDTF 一起使用,它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
2. 数据准备
3. 需求
将电影分类中的数组数据展开。结果如下:
4. 创建本地 movie.txt,导入数据
1 | shell复制代码[moe@hadoop102 datas]$ vi movie_info.txt |
- 创建 hive 表并导入数据
1 | hive复制代码hive (default)> create table movie_info |
- 按需求查询数据
1 | hive复制代码hive (default)> SELECT |
2.5、窗口函数(开窗函数)
- 相关函数说明
OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化。
CURRENT ROW:当前行
n PRECEDING:往前 n 行数据
n FOLLOWING:往后 n 行数据
UNBOUNDED:起点,
UNBOUNDED PRECEDING 表示从前面的起点,UNBOUNDED FOLLOWING 表示到后面的终点
LAG(col,n,default_val):往前第 n 行数据
LEAD(col,n, default_val):往后第 n 行数据
NTILE(n):把有序窗口的行分发到指定数据的组中,各个组有编号,编号从 1 开始,对于每一行,NTILE 返回此行所属的组的编号。注意:n 必须为 int 类型。
2. 数据准备:name,orderdate,cost
1 | txt复制代码jack,2017-01-01,10 |
- 需求
* 查询在 2017 年 4 月份购买过的顾客及总人数
* 查询顾客的购买明细及月购买总额
* 上述的场景, 将每个顾客的 cost 按照日期进行累加
* 查询每个顾客上次的购买时间
* 查询前 20%时间的订单信息
- 创建本地 business.txt,导入数据
1 | shell复制代码[moe@hadoop102 datas]$ vi business.txt |
- 创建 hive 表并导入数据
1 | hive复制代码hive (default)> create table business( |
- 按需求查询数据
* 查询在 2017 年 4 月份购买过的顾客及总人数
未使用over()函数
1
2
3
4
5
hive复制代码hive (default)> select
> name,count(*)
> from business
> where substring(orderdate,1,7) = '2017-04'
> group by name;

使用over()函数
1
2
3
4
5
hive复制代码hive (default)> select
> name,count(*) over()
> from business
> where substring(orderdate,1,7) = '2017-04'
> group by name;

* 查询顾客的购买明细及月购买总额
1
2
3
hive复制代码hive (default)> select
> name,orderdate,cost,sum(cost) over(partition by month(orderdate))
> from business;

* 将每个顾客的 cost 按照日期进行累加
1
2
3
4
5
6
7
8
9
hive复制代码select name,orderdate,cost,
sum(cost) over() as sample1,--所有行相加
sum(cost) over(partition by name) as sample2,--按 name 分组,组内数据相加
sum(cost) over(partition by name order by orderdate) as sample3,--按 name分组,组内数据累加
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和 sample3 一样,由起点到当前行的聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --当前行和前面一行做聚合
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--当前行和前边一行及后面一行
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --当前行及后面所有行
from business;

rows 必须跟在 order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量

* 查看顾客上次的购买时间
1
2
3
4
5
hive复制代码select
name,orderdate,cost,
lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1,
lag(orderdate,2) over (partition by name order by orderdate) as time2
from business;

* 查询前 20%时间的订单信息
1
2
3
4
5
hive复制代码select * from (
select name,orderdate,cost, ntile(5) over(order by orderdate) sorted
from business
) t
where sorted = 1;

2.6、Rank
- 函数说明
RANK() 排序相同时会重复,总数不会变。
DENSE_RANK() 排序相同时会重复,总数会减少。
ROW_NUMBER() 会根据顺序计算
2. 数据准备
3. 需求
计算每门学科成绩排名。
4. 创建本地 score.txt,导入数据
1 | shell复制代码[moe@hadoop102 datas]$ vi score.txt |
- 创建 hive 表并导入数据
1 | hive复制代码hive (default)> create table score( |
- 按需求查询数据
1 | hive复制代码select name, |
3、自定义函数
- Hive 自带了一些函数,比如:max/min 等,但是数量有限,自己可以通过自定义 UDF 来方便的扩展。
- 当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。
- 根据用户自定义函数类别分为以下三种
* UDF(User-Defined-Function)
一进一出
* UDAF(User-Defined Aggregation Function)聚集函数
多进一出
类似于:count/max/min
* UDTF(User-Defined Table-Generating Functions)
一进多出
如 lateral view explode()
- 官方文档地址
cwiki.apache.org/confluence/…
5. 编程步骤
* 继承 Hive 提供的类
org.apache.hadoop.hive.ql.udf.generic.GenericUDF
org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
* 实现类中的抽象方法
* 在 hive 的命令行窗口创建函数
添加 jar
1
shell复制代码add jar linux_jar_path
创建 function
1
hive复制代码create [temporary] function [dbname.]function_name AS class_name;
* 在 hive 的命令行窗口删除函数
1
hive复制代码drop [temporary] function [if exists] [dbname.]function_name;
4、自定义 UDF 函数
- 需求
自定义一个 UDF 实现计算给定字符串的长度(当然系统默认有这个函数,仅仅是案例模拟!),例如:
1 | hive复制代码hive(default)> select my_len("abcd"); |
- 创建一个 Maven 工程 Hive
- 导入依赖
1 | pom复制代码<dependencies> |
- 创建一个类
1 | java复制代码public class MyUDF extends GenericUDF { |
- 打成 jar 包上传到服务器/opt/module/hive-3.1.2/datas/myudf.jar
- 将 jar 包添加到 hive 的 classpath
1 | hive复制代码hive (default)> add jar /opt/module/hive-3.1.2/datas/myudf.jar; |
- 创建临时函数与开发好的 java class 关联
1 | hive复制代码hive (default)> create temporary function my_len as "com.moe.hive.udf.MyUDF"; |
- 即可在 hql 中使用自定义的函数
1 | hive复制代码hive (default)> select my_len('moe'); |
5、自定义 UDTF 函数
- 需求
自定义一个 UDTF 实现将一个任意分割符的字符串切割成独立的单词,例如:
1 | hive复制代码hive(default)> select myudtf("hello,world,hadoop,hive", ","); |
- 代码实现
1 | java复制代码public class MyUDTF extends GenericUDTF { |
- 打成 jar 包上传到服务器/opt/module/hive-3.1.2/datas/myudtf.jar
- 将 jar 包添加到 hive 的 classpath 下
1 | hive复制代码hive (default)> add jar /opt/module/hive-3.1.2/datas/myudtf.jar; |
- 创建临时函数与开发好的 java class 关联
1 | hive复制代码hive (default)> create temporary function myudtf as "com.moe.hive.udtf.MyUDTF"; |
- 使用自定义的函数
1 | hive复制代码hive (default)> select myudtf('hello,moe,hive',','); |
二、友情链接
本文转载自: 掘金