hive 的函数 lateral view 用法详解

select good_bey_2023,hello_2024

from newyear 
lateral view posexplode(split('hive, spark,flink ,line,line,so,easy',',')) t as lan_id_index, good_bey_2023

lateral view posexplode(split('date,todate,firstday,day,day,no,bug',',')) t as day_index, hello_2024
where lan_id_index = day_index;

预览结果应该是

good_bey_2023hello_2024
hivedate
sparktodate
flinkfirstday
lineday
lineday
sono
easybug

这里用到了hive 的 lateral view 功能,这篇文章只要介绍一下这个函数。

lateral view 简介

hive函数 lateral view 主要功能是将原本汇总在一条(行)的数据拆分成多条(行)成虚拟表,再与原表进行笛卡尔积,从而得到明细表。配合UDTF函数使用,一般情况下经常与explode函数搭配,explode的操作对象(列值)是 ARRAY 或者 MAP ,可以通过 split 函数将 String 类型的列值转成 ARRAY 来处理。

select col_A,col_B,tmp_table.tmp_col 
from table_name 
lateral view explode(split(col,'分隔符')) tmp_table as tmp_col

使用实例

转成多行

我朋友圈的代码就是栗子:

select good_bey_2023,hello_2024

from newyear 
lateral view posexplode(split('hive, spark,flink ,line,line,so,easy',',')) t as lan_id_index, good_bey_2023

lateral view posexplode(split('date,todate,firstday,day,day,no,bug',',')) t as day_index, hello_2024
where lan_id_index = day_index;

预览结果应该是

good_bey_2023hello_2024
hivedate
sparktodate
flinkfirstday
lineday
lineday
sono
easybug

汇总求和

select good_bey_2023,count(hello_2024) hello_2024

from newyear 
lateral view posexplode(split('hive, spark,flink ,line,line,so,easy',',')) t as lan_id_index, good_bey_2023

lateral view posexplode(split('date,todate,firstday,day,day,no,bug',',')) t as day_index, hello_2024
where lan_id_index = day_index
group by good_bey_2023;

explode(x)和posexplode()

explode(x)和posexplode() 均为炸裂函数,区别在于explode炸出一个值,posexplode不仅炸出一个值还附带索引号;

如何产生1-100的连续的数字?

方法一:结合space函数与split函数,posexplode函数,lateral view函数获得
select
id_start+pos as id
from(
    select
    1 as id_start,
    100 as id_end
) m  lateral view posexplode(split(space(id_end-id_start), '')) t as pos, val

方法二:
select
  row_number() over() as id
from  
  (select split(space(99), ' ') as x) t
lateral view
explode(x) ex;

如何产生开始日期到结束日期的连续的日期?

 SELECT 
 DATE_ADD(START_DATE, pos)
FROM (
 SELECT DISTINCT
  "2023-03-13" AS START_DATE,
  "2023-03-22" AS END_DATE
   from order_detail
) s1 lateral VIEW posexplode(split(SPACE(DATEDIFF(END_DATE, START_DATE)), " ")) s2 AS pos, null_ele

lateral view json_tuple(转成多列)

lateral view json_tuple 函数解析非结构化的json数据类型

工作中遇到一个数据表的存储形式,如下:

idcol1col2
1234{"part1" : "61", "total" : "623", "part2" : "560", "part3" : "1", "part4" : "1"}{"to_part2" : "0", "to_part4" : "0", "to_up" : "0", "to_part3" : "0", "to_part34" : "0"}
4567{"part1" : "451", "total" : "89928", "part2" : "88653", "part3" : "789", "part4" : "35"}{"to_part2" : "54", "to_part4" : "6", "to_up" : "65", "to_part3" : "2", "to_part34" : "3"}
7890{"part1" : "142", "total" : "351808", "part2" : "346778", "part3" : "4321", "part4" : "567"}{"to_part2" : "76", "to_part4" : "23", "to_up" : "65", "to_part3" : "14", "to_part34" : "53"}

其中col1,col2都是string类型,存放的是JSON格式的数据,JSON的key分别是:

col_namekey_list
col1[part1, part2, part3, part4, total]
col2[to_part2, to_part3, to_part4, to_part34, to_up]

使用lateral view json_tuple函数 从两列中分别选出part3,part4, to_part3,to_part4的key对应的数据值:

--使用lateral VIEW json_tuple函数解析数据
SELECT
    id,
    to_part3,
    to_part4,
    IF(part3=0,0.0, to_part3/part3) as ratio3,
    IF(part4=0,0.0, to_part4/part4) as ratio4
FROM
 {table_name}
lateral VIEW json_tuple(col1, 'part3', 'part4') json1 AS part3,part4 
lateral VIEW json_tuple(col2, 'to_part3', 'to_part4') json2 AS to_part3,to_part4
WHERE
 ...

lateral view json_tuple VS lateral view explode

之前的文章lateral view explode函数解析非结构化的map数据类型 介绍了使用explode ,  lateral view explode 函数来解析Map类型数据的key, value的应用。

初看下这两个例子很像,那么为什么这里使用later view json_tuple 而不是使用later view explode函数呢?

如果使用later view explode函数能不能达成想要的效果呢?

这里的关键点就是数据结构了。

本文中的例子,col1,col2数据类型是JSON,key是固定的,每条数据都有相同的key,即使这个key对应的值是0,也会有记录。

而上文中的例子,业务场景不一样,col1 、 col2的key不是固定的,数据类型是MAP。

col1col2
{24235:r2,98766:r3}{65432:r1,35689:r2,24577:r3}
{13245:r3}{34567:r1,87654:r3}

这是跟随实际应用场景而选择的数据存储类型。

比如本文中,场景类型有限,就是(part1, part2, part3, part4,to_part2, to_part3, to_part4, to_part34 )这几类,所以使用JSON的形式,穷举key来保存数据是合适的。

在电商业务中,广告触点类型非常的多(多到成百上千),而一个用户进入电商网站,实际接触到的广告触点类型却是很少的(几个到几十个),这时候如果还用JSON类型穷举所有广告触点的key,就会发现大量key的值是0,这是一个稀疏数据,这是很浪费空间的。所以,这种情况下一般采用MAP数据类型,只保留有实际意义的key和对应的值。

所以,使用later view explode函数能通过将每条数据拆分成key、value的形式来使用。

而如果使用later view json_tuple函数的话,如果在一条数据中没有指定想要的key,那么就会报错失败了。

outer lateral view

later view 前面还可以加上一个 outer 关键字,这是为了避免 当udtf 没有得到任何结果时最终虚拟结果表里丢失原数据行的问题。具体来将,由于later view 的工作原理是将原表与 udtf 产生的虚拟表做 inner join 操作,所以如果 udtf 不产生任何结果时,那么对应原表的那一行也会在 inner join 操作后消失。outer关键字就是来解决这个问题的,加上这个关键字之后执行的就是 outer join 操作了,因此原表数据会被完全保留下来。

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
课程概述教会学员快速学会python数据分析,覆盖python基础,pandas,seaborn,matplotlib,SQL,sqlite,lambda等知识。课程是数据科学家居家必备的军火库。课程定期更新,大部分视频分辨率支持2K超清,学员可以看清每一行代码。 适合人群python数据科学从业人员,数据分析师,统计 学习计划和方法1.每天保证1-2个小时学习时间,预计7-15天左右可以学习完整门课程(不同基础学生时间差异较大)。2.每节课的代码实操要保证,建议不要直接复制粘贴代码,自己实操一遍代码对大脑记忆很重要,有利于巩固知识。3.第二次学习时要总结上一节课内容,必要时做好笔记,加深大脑理解。4.不懂问题要罗列出来,先自己上网查询,查不到的可以咨询老师。 作者介绍Toby,持牌照金融公司担任模型验证专家,国内最大医药数据中心数据挖掘部门负责人!和清华大学出版社,重庆儿科医院,中科院教授,赛柏蓝保持慢病数据挖掘项目合作!管理过欧美日中印巴西等国外药典数据库,马丁代尔数据库,FDA溶解度数据库,临床试验数据库,WHO药物预警等数据库。原创公众号(python风控模型) 课程概述教会学员快速学会python数据分析,覆盖python基础,pandas,seaborn,matplotlib,SQL,sqlite,lambda等知识。课程是数据科学家居家必备的军火库。课程定期更新,大部分视频分辨率支持2K超清,学员可以看清每一行代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

douluo998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值