Hive与Presto中的列转行区别

6 篇文章 0 订阅




1、背景描述


在处理数据时,我们经常会遇到一个字段存储多个值,这时需要把一行数据转换为多行数据,形成标准的结构化数据

例如,将下面的两列数据并列转换为三行,使得codename一一对应

idcodename
1a、b、cA、B、C

Hive、Spark和Presto都提供了这种实现,但有所不同。下面通过这个案例介绍三者之间的区别及注意事项

2、Hive/Spark列转行


Hive和Spark都可以使用lateral view posexplode实现:

select id, pos1, sub_code, pos2, sub_name from tmp
lateral view posexplode(split(code,'、')) v1 as pos1, sub_code
lateral view posexplode(split(name,'、')) v2 as pos2, sub_name
where id='1' and pos1=pos2

Hive On MapReduce与Hive On Spark的执行结果如下:

idsub_codesub_name
1aA
1bB
1cC

值得注意的是,lateral view posexplode会自动过滤被转换列字段值为空的数据,进而导致数据丢失

优化方案是将lateral view修改为lateral view outer后尝试

更多关于lateral view UDTF的使用见文章:传送门

3、Presto列转行


使用PrestoSQL的交叉连接cross join unnest实现:

with t1 as(
    select id,sub_code,row_number() over() rn
    from temp
    cross join unnest(split(code, '、')) as t (sub_code)
    where id='1'
),
t2 as (
    select id,sub_name,row_number() over() rn
    from temp
    cross join unnest(split(name, '、')) as t (sub_name)
    where id='1'
)
select t1.id, t1.sub_code, t2.sub_name
from t1
left join t2 
on t1.rn = t2.rn
order by t1.rn

PrestoSQL的执行结果如下:

idsub_codesub_name
1bB
1aA
1cC

需要注意的是,cross join unnest不会自动过滤被转换列和转换列字段值为空的数据,因此此方式数据不会丢失

例如,当转换列字段值存在空值时:

idcodename
1a、b、cA、B

cross join unnest列转行的结果为

idsub_codesub_name
1aA
1cNULL
1bB

当被转换列字段值存在空值时:

idcodename
1a、b、cNULL

cross join unnest列转行的结果为

idsub_codesub_name
1bNULL
1aNULL
1cNULL


  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值