LATERAL VIEW EXPLODE 重要特性

核心概念
explode(): 是一个 UDTF(User-Defined Table-Generating Function)。它接收一个数组或映射作为输入,并将其中的每个元素输出为一行。
它本身不能直接与表中的其他列一起查询。

LATERAL VIEW: 它的作用是将 UDTF(如 explode())生成的结果虚拟表与原始表的每一行进行关联(类似于侧向连接),
从而允许你在一个 SELECT 语句中同时查询原始列和爆炸后的列。

简单比喻:
想象你的原始表是一盒巧克力(每一行是一颗巧克力),有些巧克力里面包含多个果仁(数组)。explode() 就是把巧克力掰开,
取出每一颗果仁。LATERAL VIEW 的作用就是确保你能清楚地知道每一颗果仁是从哪一颗巧克力里取出来的。

语法
sql
SELECT 
    original_column1,
    original_column2,
    exploded_column
FROM original_table
LATERAL VIEW explode(complex_data_column) virtual_table_name AS exploded_column

complex_data_column : 要展开的数组或映射类型的列。
virtual_table_name : 为 explode() 生成的虚拟表指定一个别名(表名)。
exploded_column : 为 explode() 生成的虚拟表中的列指定一个别名(列名)。

示例详解
示例 1:展开数组(Array)
假设我们有一个 user_hobbies 表,记录了每个用户及其爱好(爱好以数组形式存储)。

user_id	user_name	hobbies
1	Alice	["hiking", "music"]
2	Bob	["reading", "game", "cooking"]
3	Charlie	["sports"]
我们想将每个爱好展开成单独的一行。

sql
SELECT 
  user_id,
  user_name,
  single_hobby
FROM user_hobbies
LATERAL VIEW explode(hobbies) hobbies_table AS single_hobby;
结果与解释:

user_id	user_name	single_hobby
1	Alice	hiking
1	Alice	music
2	Bob	reading
2	Bob	game
2	Bob	cooking
3	Charlie	sports

关键点:

原始表中 user_id=1 的一行(包含2个爱好),被展开成了两行。
原始表中 user_id=2 的一行(包含3个爱好),被展开成了三行。
原始表中的每一列(user_id, user_name)都与展开后的 single_hobby 正确关联。

示例 2:展开映射(Map)
假设我们有一个 product_scores 表,记录了产品来自不同平台的评分(评分以 Map 形式存储,key 是平台名,value 是分数)。

product_id	product_name	scores
101	iPhone	{"AppStore":4.8, "Google":4.5, "Web":4.7}
102	Galaxy	{"AppStore":4.6, "Web":4.4}
我们想将每个平台的评分展开成 平台 | 分数 这样的格式。

sql
SELECT 
  product_id,
  product_name,
  platform,
  score
FROM product_scores
LATERAL VIEW explode(scores) scores_table AS platform, score;
结果与解释:

product_id	product_name	platform	score
101	iPhone	AppStore	4.8
101	iPhone	Google	4.5
101	iPhone	Web	4.7
102	Galaxy	AppStore	4.6
102	Galaxy	Web	4.4
关键点:

当 explode() 一个 Map 时,需要为虚拟表指定两个别名:一个用于接收 Key,一个用于接收 Value。

原始表中 product_id=101 的一行(包含3个键值对),被展开成了三行。

示例 3:处理空数组或 NULL - 使用 OUTER LATERAL VIEW
默认情况下,如果数组为 NULL 或空([]),explode() 不会生成任何行,导致原始表的这一行在结果中完全消失。
如果你希望保留这一行(即使没有可展开的元素),可以使用 OUTER LATERAL VIEW。

假设用户 David 没有爱好(空数组)。

user_id	user_name	hobbies
4	David	[]
sql
-- 使用 LATERAL VIEW (默认行为,David 会消失)
SELECT ... FROM user_hobbies
LATERAL VIEW explode(hobbies) h_tbl AS hobb;

-- 使用 OUTER LATERAL VIEW (David 会被保留,hobb 为 NULL)
SELECT ... FROM user_hobbies
OUTER LATERAL VIEW explode(hobbies) h_tbl AS hobb;
结果对比:

方式	user_id	user_name	single_hobby
LATERAL VIEW	1	Alice	hiking
1	Alice	music
...	...	...
(David 不在结果中)		
OUTER LATERAL VIEW	1	Alice	hiking
1	Alice	music
...	...	...
4	David	NULL
示例 4:同时展开多个数组
如果要展开的多个数组长度不一致,直接展开会产生笛卡尔积,这通常不是你想要的结果。更常见的做法是使用 posexplode()(带位置的展开)来确保对应关系。

假设有表 user_skills,包含技能和熟练度两个数组。

user_name	skills	proficiency
Alice	["SQL", "Java"]	[90, 80]
sql
-- 错误做法:会产生 2 x 2 = 4 行,错误关联
SELECT 
  user_name,
  skill,
  prof
FROM user_skills
LATERAL VIEW explode(skills) s AS skill
LATERAL VIEW explode(proficiency) p AS prof;

-- 正确做法:使用 posexplode 按索引关联
SELECT 
  user_name,
  skill,
  prof
FROM user_skills
LATERAL VIEW posexplode(skills) s AS skill_idx, skill
LATERAL VIEW posexplode(proficiency) p AS prof_idx, prof
WHERE skill_idx = prof_idx;
总结与用途
特性	说明
主要用途	处理嵌套的复杂数据类型(Array, Map),将其"扁平化"为标准SQL表格式,以便进行关联、过滤、聚合等后续操作。
核心组件	LATERAL VIEW + explode() / posexplode() / 其他 UDTF
性能注意	爆炸操作可能会显著增加数据量(一行变多行),需谨慎使用。
应用场景	1. 用户标签分析:一个用户有多个标签,展开后分析标签分布。
2. 日志解析:一条日志包含多个事件ID或错误码,展开后进行统计。
3. 商品属性处理:一个商品有多个分类或多个价格(针对不同平台),展开后关联查询。
一句话总结:LATERAL VIEW explode() 是将 Hive 中"一行对多值"的列式存储,转换为标准SQL"一行一值"关系型表格的核心工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值