lateral view 为侧视图,一般用于行转列的处理中 通常会与explode 搭配使用
1、explode 可以拆分map or array
示例
select explode(split("1,2,3",','))
结果
1 |
2 |
3 |
explode 不适用于多个字段 其中一个字段需要炸开的场景,此时需要搭配lateral view
2、lateral view explode
示例:
原始数据
name | goods | order |
a | book,food | 1,2 |
b | computer,pingpong ball | 2,3 |
select name,goods1,order1
from
(
select 'a' name,'book,food' as goods,'1,2' as order
union all
select 'b' name,'book,food' as goods,'1,2' as order
)a
lateral view explode(split(goods, ',')) t_course as goods1
lateral view explode(split(order, ',')) t_hobby as order1
结果
name | goods1 | order1 |
a | book | 1 |
a | book | 2 |
a | food | 1 |
a | food | 2 |
b | computer | 2 |
b | computer | 3 |
b | pingpong ball | 2 |
b | pingpong ball | 3 |
当name = a goods = null 时结果如下:会发现name=a的都被过滤掉了,如果需要展示name=a的数据则需要 加outer来解决,具体见下一节的内容
name | goods1 | order1 |
b | computer | 2 |
b | computer | 3 |
b | pingpong ball | 2 |
b | pingpong ball | 3 |
3、lateral view outer
假设需要炸开的字段 数组为空,此时使用lateral view 去炸开的时候 会得到结果为null,没有数据,此时需要使用outer字段 才可以正常展示数据。
原因在于:
lateral view ,原理是如果被炸开的字段为null 直接返回null
lateral view outer 则会保留原始的数据,并将炸开的列置为null
以上述图表为例lateral view 类似为 inner join 约为 :
由图可以看出 当goods 或者order 为空数组时 结果会为null
而 lateral view outer 则类似与 outer join
当goods 为null 时 炸开的列 会填充为null ,不会丢失原始被筛选出来的列
但实际上lateral view不会产生shuffle,实际是拼接字符串
所以当数据出现的结果 与预期不一致的时候 可以排查一下 炸开的字段里面是否有空数组,做好数据探查,明确用户真实想要的结果是什么