Hive SQL 中ARRAY或MAP类型数据处理:lateral view explode()/posexplode()——行转列函数

文章介绍了在Hive中如何使用lateralview和explode()函数来处理array或map类型的字段,通过举例说明了当需要将数组或映射的每个值拆分并与其关联字段形成一一对应时的操作方法,包括split()、posexplode()的使用,以及处理map类型字段的问题。此外,还提到了lateralview的使用注意事项和如何处理null值的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:在对表数据进行批量处理过程中,常常碰上某个字段是一个array或者map形式的字段,一列数据的该字段信息同时存在多个值,当我们需要取出该数组中的每一个值实现一一对应关系的时候,可以考虑使用lateral view explode()/posexplode() 进行处理。

一、提要:explode()本身是Hive的自带函数,使用它可以将array或者map中的值逐行输出。

select explode(array('a','b','c','d','e'));

select explode(map('A','a','B','b','C','c'));

二、应用:lateral view explode()在工作环境中的使用。(lateral view用于和split、explode等UDTF一起使用的,能将一行数据拆分成多行数据,在此基础上可以对拆分的数据进行聚合,lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一行或者多行,lateral view在把结果组合,产生一个支持别名表的临时表。)

如下国家地区表dim_country,需要实现将shortname(array类型)中的国家简写逐个拆分出来实现与id及level的一一对应。

 如果只是用explode()会出现报错,因为explode()只能实现将shortname单字段进行炸开,一行变多行,但是id和level只有一行,故无法形成新表,这时候就需要用到lateral view。使用lateral view explode()可以将炸出的多行以临时表tmp的形式存在,其它的字段会进行相应的复制,实现与tmp的一一对应。

select id,level,country 
from dim_country
lateral view explode(shortname)tmp as country ;

(tips:即使数组中各元素相同,也都会一一列出)

 三、补充:split()函数的应用

如果需要lateral view explode()的字段类型是string,则需要用split()函数将之拆分成数组,然后再用lateral view explode()处理。同上dim_country表,如果shortname是string类型,则HQL如下,结果相同。

select id,level,country 
from dim_country
lateral view explode(split(shortname,’,’))tmp as country ;

正常数组类型两侧会带有[],但有些时候也可能是string类型,如果是string类型且两侧带有[],则需要先用substring()将两侧的[]去掉,可以考虑用如下方式:

SELECT regexp_replace(substr(shortname,2),substr(substr(shortname,2),-1,1),'');
或 
SELECT substr(shortname,2,length(shortname)-2);

&相关资料:试验过程的建表及插入SQL:

建表语句:
CREATE table dim_country (id bigint,level int,shortname ARRAY<string>);
插入语句(两种形式):
insert into table dim_country values (1,1,array('US','CA','UK'));
insert into dim_country(id,level,shortname) select 1,1,array('US','CA','AE');
insert into dim_country(id,level,shortname) select 1,1,array('US','US');

四、进阶:lateral view explode()在map类型上的使用问题及解决方法(lateral view posexplod() )。

        1、建表

CREATE table dim_map (id bigint,level int,shortname MAP<string,string>)
ROW FORMAT DELIMITED fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';

        2、插入数据

insert into table dim_map 
values (1,1,str_to_map('yuwen:aaa,shuxue:bbb,yingyu:ccc,wuli:ddd,huaxue:eee'));

insert into dim_map(id,level,shortname) 
values (1,1,str_to_map('yuwen:100,shuxue:98,yingyu:88,wuli:89,huaxue:100'));

         3、explode()实现对map类型字段的炸开,形成key和value两段(但只能是map类型字段本身,不能另加别的字段)

SELECT explode(shortname) from dim_map;

         4、如果要加另外的字段,需要用到lateral view posexplod() 函数。

SELECT id,level,single_id,single_time from temp.dim_map
LATERAL VIEW posexplode(map_keys(shortname))t as single_id_index,single_id
LATERAL VIEW posexplode(map_values(shortname))t 
as single_time_index,single_time
where single_id_index = single_time_index;

posexplode()可以炸开一个数组,会形成两列,一列是自增序列,一列是炸出来的值。上诉方法则是通过自增序列实现一一对应结合。

 posexplode()可以通过与split(space(n))结合,可以实现插入固定的行数。

        5、补充:map_key()和map_value()可以直接对取出一个map中的所有key和所有value

SELECT id,level,map_keys(shortname), map_values(shortname) from temp.dim_map;

 五、使用lateral view注意事项:

1. lateral view使用在from后,where前,参照如下格式;

lateral view explode(数组字段)临时表名 as 别名 ;

2. from后可带多个lateral view;

3. 如果要拆分的字段有null值,需要使用lateral view outer 替代,避免数据缺失。

参考链接:

Hive SQL中的lateral view explode_IT农民工1的博客-CSDN博客

http://t.zoukankan.com/share23-p-10173311.html 

Hive-sql中的explode()函数和posexplode()函数_sql中explode_有语忆语的博客-CSDN博客

### Hive SQL行转列和列转行的实现方法 #### 行转列 (Pivot) 在Hive SQL中,行转列通常通过`GROUP BY`语句配合聚合函数来完成。对于更复杂的场景,则可以利用内置函数如 `collect_set()` 者 `concat_ws()`. 当需要将某列中的不同值汇总成一行并以特定字符分隔时,可采用如下方式: ```sql SELECT id, CONCAT_WS(',', COLLECT_SET(value_column)) AS aggregated_values FROM table_name GROUP BY id; ``` 此查询会把表内相同ID下的value_column字段的不同取值收集起来形成一个由逗号分隔的字符串[^4]. #### 列转行 (Unpivot) 针对列转行为需求,Hive提供了专门用于展开数组map类型的两个重要工具——`LATERAL VIEW` 结合 `EXPLODE` 及其变体 `POSEXPLODE`. - **Explode**: 将单个单元格内的复杂数据结构拆分成多条记录. 假设有一个包含多个标签的字符串列表作为单一字段存储: ```sql SELECT t.id, e.tag FROM tags_table t LATERAL VIEW EXPLODE(SPLIT(t.tags, ',')) exploded_table AS e; ``` 上述命令将会依据逗号分割tags字段,并为每一个子项创建新的行. - **Posexplode**: 类似于explode功能但是额外返回元素的位置索引。 如果想要获取位置信息的话就可以这样写: ```sql SELECT t.id, p.pos, p.value FROM complex_data t LATERAL VIEW POSEXPLODE(array_field) posexpanded_table AS pos, value; ``` 为了进一步处理含有不确定层级的数据集,在某些情况下可能还需要嵌套使用这些操作以便达到预期效果[^3]. 同样地,如果面对的是已知固定数量级别的转换任务,则可以直接指定各级别的映射关系来进行变换[^2].
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值