大家好,我是摇光~,用大白话讲解全部你难明的知识点
之前在学习 hive 的时候,看了很多文章写 UDTF函数,但是都没有讲得很懂。
以是我照旧按照我的习惯,大白话讲解 UDTF函数,包含对lateral view 、explode等讲解。
一、UDTF 函数
想要学习 lateral view explode,我们先来相识一下 UDTF 函数。
1、UDTF函数是什么?
- UDTF函数是用户自定义表生成函数。
(实在你不需要理解这个意义,只需要知道他就是个函数就行)
2、UDTF函数的作用是什么?
- 将一行数据转换成多行数据。
- 好比你的表长成下图左边这样,但是这样的数据不便于统计
- 以是你就需要将他转成右边这样子,这样便于统计
我们如今应该就理解 UTDF 函数具体能给我们带来什么了,接下来我们来相识一下 hive 里面有哪些常见的 UTDF 函数。
3、UTDF函数有哪些常见函数?
- explode:将array或map拆分成独立的行。
- posexplode:类似于explode,但同时生成每个元素的位置索引。可用于带有位置信息的数组数据。
- inline:将嵌套的数组或映射中的每个元素拆分成独立的行。
- stack:将多个值堆叠成多行。
- json_tuple:从JSON字符串中提取多个字段。
上面这么多 UDTF 函数,大家是不是看得有点懵;固然有这么多,但是实在只需要相识到一个,并知其原理,就融会贯通了。
接下来我们用 explode 来进行讲解:
先来看看语法:
以下是对三种数据类型进行 explode,array、map、string三种类型
- # array_col 是array类型, 是需要进行转换的字段
- select explode(array_col) as newcol from mytable;
复制代码
- # map_col 是map类型, 是需要进行转换的字段
- # keyname:表示key转换成的列名称;valuename:表示value转换成的列名称
- select explode(map_col) as (keyname,valuename) from mytable;
复制代码
- # expload 不支持string类型,但是可以通过split转成array类型
- select explode(split(string_col,'分隔符')) as (keyname,valuename) from mytable;
复制代码 我们来举个例子:(由于很多时候都接纳字符串,以是利用字符串举例。)
好比上面左边这张表,一个字段是老师,别的一个字段是所教的班级。需要将班级这个字段进行一行转多行。
代码:
- # 根据这样写,就会将班级这个字段转成多行,像上图右边那样。
- select explode(split(班级,'、')) from mytable;
复制代码 注意:这里形成了一个新表,不能查询到原表的数据,假如加上字段“老师”就会报错
看到这里大家应该知道假如就利用 explode 的话,有很多弊端。
- 不能关联原表中其他字段
- 不能利用 group by、sort by 等分组
有上面这些弊端,我们就需要去办理,以是引入了 lateral view 。
二、Lateral View explode
Lateral View 是不能单独利用,它必须与UDTF(User-Defined Table-Generating Function)一起利用。
Lateral View explode 是怎么运作的?
- 1、Lateral View 起首为原始表的每行调用 UDTF
- 2、UDTF 将一行拆分成一行或多行
- 3、Lateral View 再将结果组合,产生一个支持别名表的虚拟表
总结一下:
实在就相当于 Lateral View explode 产生一张虚拟表,然后和原表进行笛卡尔积相连。
通过上面的表明,应该就懂得什么是Lateral View explode了吧,也知道为啥搜索 explode 就会出现 Lateral View 了。
那我们如今来看看语法:
- select col1,tmp_table.tmp_col
- from mytable
- lateral view explode(col2) tmp_table as tmp_col2,(tmp_col2)*
- lateral view explode(col3) tmp_table as tmp_col3,(tmp_col3)*
- # col_A,col_C: 是表 mytable 的字段
- # tmp_table:explode 形成的新虚拟表,可以不写
- # lateral view:虚拟表和原表进行笛卡尔积关联
- # tmp_col,(tmp_col)*:explode 形成的新列(字段),如果产生多个字段,可以用逗号隔开。
- # 可以跟多个lateral view语句,使用空格间隔就可以了。
复制代码 可能看着语法照旧有点懵,我用一张示意图来表示一下 explode 的用法。
题目:
- 从上面图片可以看出,左边的数据是 任务 “Task1 ” 的处理人有 “张三、李四”;假如我想知道“张三”这个人一共涉及到多少个任务?
答复:
- 那么我们就需要将表转成右边的样子,这样就可以统计出每个人的任务数量。
让我们来写一下sql:
- select 任务,tmp_col
- from task_table
- lateral view explode(split(处理人,'、')) tmp_table as tmp_col;
- # 因为处理人字段的数据是字符串,所以我们需要将他进行拆分。
- # 所以使用了 split(处理人,'、') ,使用 '、'进行拆分。
复制代码
- 我们还可以利用 group by 进行数据统计,好比统计每个人员有多少个待办任务。
- select 人员,count(人员)
- from task_table
- lateral view explode(split(处理人,'、')) tmp_table as 人员
- group by 人员;
- # 加上 count(人员)和group by 人员;就可以对每个人有多少任务进行统计了。
复制代码 三、实际案例
上面我们学习了 Lateral View explode 是什么,和大抵用法。
接下来我们用几个例子来巩固一下所学的。
实在假如光利用 Lateral View explode 感觉也得不出什么,以是需要利用一些分组函数、聚合函数、排序函数来组合利用,就会达到一些意想不到的效果。
1、盘算每日贩卖最高、最低
题目:
解题思路:
- 1、先将“贩卖量”字段进行 UDTF 变成多行数据
- 2、再进行分组排序,取最低和最高
代码:
- select
- 日期,fruit,sale
- from(
- select
- 日期
- ,fruit
- ,sale
- ,rank()over(partition by 日期 order by sale) rn1 # 对日期进行分类,sale销售量排序
- ,rank()over(partition by 日期 order by sale desc) rn2 # 对日期进行分类,sale销售量排序
- from fruits_sale
- Lateral View explode(销售量) sale_table as fruit,sale # 分列成两列
- ) t
- where t.rn1 = 1 or t.rn2 = 1 # 取排序第一的
复制代码 2、统计天天客容量是多少
题目:
解题思路:
- 1、退房时间 - 入住时间 得到具体相差几天
- 2、通过 Lateral View posexplode 将每一行分成相差几天的天数
- 3、再进行 group by 日期 count() 统计总数
- select
- 开始日期,结束日期,count(1),sum(人数)
- from(
- select
- 顾客
- ,人数
- ,date_add(入住时间,pos) as 开始日期
- ,date_add(入住时间,pos+1) as 结束日期
- from cus_table
- Lateral View
- posexplode(split(repeat('R,',datediff(入住时间,退房时间)),',')) tmp as pos,value
- ) t
- group by 开始日期,结束日期
复制代码 上面的代码实在主要理解三个点:
1、posexplode(split(repeat(‘R,’,datediff(入住时间,退房时间)),‘,’)) tmp as pos,value
- datediff(入住时间,退房时间) :是相减得到共入住几天
- repeat(‘R,’,datediff(入住时间,退房时间)):构建 string 字符串,repeat 是重复字符串
- split(repeat(‘R,’,datediff(入住时间,退房时间)),‘,’):再对构建的字符串进行拆分
- posexplode(split(repeat(‘R,’,datediff(入住时间,退房时间)),‘,’)) :pos 是记载位置,从 0开始
2、date_add(入住时间,pos) as 开始日期
3、date_add(入住时间,pos+1) as 结束日期
- 好比入住有 5 天,则pos字段就是 0,1,2,3,4 ;则用入住日期加上 pos ,就可以让一条数据,变成五条数据;并且开始日期和结束日期只差一天。
以上就是我对 UTDF 的一些理解,假如有什么疑问,或者还有什么想学习的,接待大家背景私信或者评论~
我将积极用大白话让你理解到高深莫测的东西。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |