背景
LATERAL VIEW:侧视图,用来将数组 / Map 等集合字段炸开多行,实现一对多关联
posexplode():爆炸函数,和 explode 类似,但同时返回下标位置 + 元素值
LATERAL VIEW posexplode(数组字段) AS pos, val
作用:把数组拆成多行,额外带出每个元素在数组中的索引下标
explode vs posexplode 核心区别
explode(arr)
只输出数组里的元素,没有下标
explode(array('a','b','c'))ASval结果:
val a b cposexplode(arr)
输出两列:pos(下标,从 0 开始)、val(元素)
posexplode(array('a','b','c'))ASpos,val结果:
pos val 0 a 1 b 2 cLATERAL VIEW 作用
如果直接 select posexplode(col),只能单独查爆炸函数;
当需要同时查询原表普通字段 + 炸开后的多行数据,必须搭配 LATERAL VIEW
标准语法模板
SELECT原表普通字段,pos,-- 数组下标val-- 数组元素FROM表名 LATERALVIEWposexplode(数组字段)tmpASpos,val;tmp:侧视图别名(可省略,建议写上)
pos:自定义下标列名
val:自定义元素列名
实战示例
id name hobby_list 1 小明 ["篮球","游戏"] 2 小红 ["看书","画画","跑步"]SELECTid,name,pos,hobbyFROMuser_info LATERALVIEWposexplode(hobby_list)tASpos,hobby;输出结果
id name pos hobby 1 小明 0 篮球 1 小明 1 游戏 2 小红 0 看书 2 小红 1 画画 2 小红 2 跑步常见使用场景
需要区分数组元素顺序
比如日志数组按时间有序,pos 代表第几条行为;
取数组第 N 个元素做过滤
-- 只保留数组第一个元素(pos=0)WHEREpos=0有序数组转宽表
根据 pos 做行转列 collect_list + case when pos=x;
有序标签打分:下标越小权重越高,pos 参与计算。
关键特性 & 坑点
下标从 0 开始,不是 1
数组为 null / [] 空数组:整条行会消失(不生成任何行)
想保留空行用
LATERALVIEWOUTERposexplode(...);支持嵌套:多个 LATERAL VIEW 连续写,拆解多层数组;
Map 类型配套:posexplode(map) 会返回 pos, key, value 三列
OUTER 关键字补充(保留空数据)
不加 OUTER:数组为空则主表这条数据直接丢失
加 OUTER:数组为空时 pos=null, val=null,主表数据保留
LATERALVIEWOUTERposexplode(hobby_list)tASpos,hobby