【hive Lateral View explode 详解】—— 大白话讲解 explode 和 Lateral V ...

打印 上一主题 下一主题

主题 865|帖子 865|积分 2595

大家好,我是摇光~,用大白话讲解全部你难明的知识点
之前在学习 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类型
  1. # array_col 是array类型, 是需要进行转换的字段
  2. select explode(array_col) as newcol from mytable;
复制代码


  • map类型
  1. # map_col 是map类型, 是需要进行转换的字段
  2. # keyname:表示key转换成的列名称;valuename:表示value转换成的列名称
  3. select explode(map_col) as (keyname,valuename) from mytable;
复制代码


  • string 类型
  1. # expload 不支持string类型,但是可以通过split转成array类型
  2. select explode(split(string_col,'分隔符')) as (keyname,valuename) from mytable;
复制代码
我们来举个例子:(由于很多时候都接纳字符串,以是利用字符串举例。)

好比上面左边这张表,一个字段是老师,别的一个字段是所教的班级。需要将班级这个字段进行一行转多行。
代码:
  1. # 根据这样写,就会将班级这个字段转成多行,像上图右边那样。
  2. 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 了。
那我们如今来看看语法:
  1. select col1,tmp_table.tmp_col
  2. from mytable
  3. lateral view explode(col2) tmp_table as tmp_col2,(tmp_col2)*
  4. lateral view explode(col3) tmp_table as tmp_col3,(tmp_col3)*
  5. # col_A,col_C: 是表 mytable 的字段
  6. # tmp_table:explode 形成的新虚拟表,可以不写
  7. # lateral view:虚拟表和原表进行笛卡尔积关联
  8. # tmp_col,(tmp_col)*:explode 形成的新列(字段),如果产生多个字段,可以用逗号隔开。
  9. # 可以跟多个lateral view语句,使用空格间隔就可以了。
复制代码
可能看着语法照旧有点懵,我用一张示意图来表示一下 explode 的用法。

   题目:
  

  • 从上面图片可以看出,左边的数据是 任务 “Task1 ” 的处理人有 “张三、李四”;假如我想知道“张三”这个人一共涉及到多少个任务?
    答复:
  

  • 那么我们就需要将表转成右边的样子,这样就可以统计出每个人的任务数量。
  让我们来写一下sql:
  1. select 任务,tmp_col
  2. from task_table
  3. lateral view explode(split(处理人,'、')) tmp_table as tmp_col;
  4. # 因为处理人字段的数据是字符串,所以我们需要将他进行拆分。
  5. # 所以使用了 split(处理人,'、')  ,使用 '、'进行拆分。
复制代码


  • 我们还可以利用 group by 进行数据统计,好比统计每个人员有多少个待办任务。
  1. select 人员,count(人员)
  2. from task_table
  3. lateral view explode(split(处理人,'、')) tmp_table as 人员
  4. group by 人员;
  5. # 加上 count(人员)和group by 人员;就可以对每个人有多少任务进行统计了。
复制代码
三、实际案例

上面我们学习了 Lateral View explode 是什么,和大抵用法。
接下来我们用几个例子来巩固一下所学的。
实在假如光利用 Lateral View explode 感觉也得不出什么,以是需要利用一些分组函数、聚合函数、排序函数来组合利用,就会达到一些意想不到的效果。
1、盘算每日贩卖最高、最低



  • 数据表

   题目:
  

  • 怎么盘算天天哪种水果贩卖量最高,哪种贩卖量最低?
    解题思路:
  

  • 1、先将“贩卖量”字段进行 UDTF 变成多行数据
  • 2、再进行分组排序,取最低和最高
  代码:
  1. select
  2.         日期,fruit,sale
  3. from(
  4.         select
  5.                 日期
  6.                 ,fruit
  7.                 ,sale
  8.                 ,rank()over(partition by 日期 order by sale) rn1                # 对日期进行分类,sale销售量排序
  9.                 ,rank()over(partition by 日期 order by sale desc) rn2        # 对日期进行分类,sale销售量排序
  10.         from fruits_sale
  11.         Lateral View explode(销售量) sale_table as fruit,sale                # 分列成两列
  12.         ) t
  13. where t.rn1 = 1 or t.rn2 = 1                                                                        # 取排序第一的
复制代码
2、统计天天客容量是多少



  • 数据表

   题目:
  

  • 怎么盘算天天有多少房间在利用,最多有多少客人?
    解题思路:
  

  • 1、退房时间 - 入住时间 得到具体相差几天
  • 2、通过 Lateral View posexplode 将每一行分成相差几天的天数
  • 3、再进行 group by 日期 count() 统计总数
  1. select
  2.         开始日期,结束日期,count(1),sum(人数)
  3. from(
  4.         select
  5.                 顾客
  6.                 ,人数
  7.                 ,date_add(入住时间,pos)        as 开始日期
  8.                 ,date_add(入住时间,pos+1) as 结束日期
  9.         from cus_table
  10.         Lateral View
  11.         posexplode(split(repeat('R,',datediff(入住时间,退房时间)),',')) tmp as pos,value
  12. ) t
  13. 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企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

千千梦丶琪

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表