跳到主要内容

explode:数组/Map 拆分为多行

速查结论

explode(expr) 是 Spark SQL 中用于将数组或 Map 拆分为多行的函数。数组元素默认列名为 col,Map 元素默认列名为 keyvalue。注意:explode 只能出现在 SELECT 子句中,且不能与其他普通列直接并列 SELECT(需配合 lateral view),否则会报错。

语法

explode(expr)
-- 或使用命名参数
explode(collection => expr)

参数说明

参数说明
expr数组(Array)或映射(Map)类型的表达式

返回值

  • 输入为数组:返回多行,每行包含数组的一个元素,默认列名为 col
  • 输入为 Map:返回多行,每行包含一个键值对,默认列名为 keyvalue

Since: 1.0.0

示例

数组拆分

-- 基础用法:数组拆分为多行
SELECT explode(array(10, 20));
-- 结果:
-- 10
-- 20

-- 使用命名参数
SELECT explode(collection => array(10, 20));
-- 结果同上

-- 用 SELECT * 展示
SELECT * FROM explode(collection => array(10, 20));
-- 结果:
-- 10
-- 20

Map 拆分

-- Map 拆分为 key 和 value 两列
SELECT explode(map('a', 1, 'b', 2, 'c', 3));
-- 结果:
-- a 1
-- b 2
-- c 3

Lateral View 结合使用

当需要将 explode 结果与原表其他列一起展示时,必须使用 LATERAL VIEW

-- 正确写法:LATERAL VIEW 展开数组并保留原表列
SELECT
user_id,
item
FROM orders
LATERAL VIEW explode(items) AS item;

-- 多个数组同时展开
SELECT
user_id,
name,
score
FROM students
LATERAL VIEW explode(names) AS name
LATERAL VIEW explode(scores) AS score;

Lateral View Outer — 保留 NULL / 空数组

-- LATERAL VIEW:空数组会导致整行消失
SELECT user_id, tag
FROM users
LATERAL VIEW explode(tags) AS tag;
-- tags 为空数组的行会被完全丢弃

-- LATERAL VIEW OUTER:空数组的行保留,tag 为 NULL
SELECT user_id, tag
FROM users
LATERAL VIEW OUTER explode(tags) AS tag;
-- tags 为空数组的行保留,tag 列为 NULL

explode vs explode_outer vs posexplode 对比

函数输入类型输出空数组/Map 行为
explode(expr)Array / Map单列(col) / 双列(key, value)该行被丢弃
explode_outer(expr)Array / Map同 explode该行保留,值为 NULL
posexplode(expr)Array双列(pos, col),pos 为元素索引(从0开始)该行被丢弃
-- explode: 空数组行丢弃
SELECT explode(array()) AS col;
-- 结果: 空

-- explode_outer: 空数组行保留为 NULL
SELECT explode_outer(array()) AS col;
-- 结果: NULL

-- posexplode: 返回元素位置 + 值
SELECT posexplode(array('a', 'b', 'c'));
-- 结果:
-- 0 a
-- 1 b
-- 2 c

常见报错与避坑指南

explode 与普通列并列 SELECT

-- 错误写法:explode 不能直接与普通列并列 SELECT
SELECT id, explode(items) FROM orders;
-- AnalysisException: The number of aliases supplied does not match the number of columns
-- 或: Generators are not supported outside the SELECT list

-- 正确写法:使用 LATERAL VIEW
SELECT id, item
FROM orders
LATERAL VIEW explode(items) AS item;

嵌套数组未展开就访问

-- 错误写法:嵌套数组需要两次 explode
SELECT explode(nested_array) FROM t;
-- 结果: 每个元素仍然是数组,不是标量值

-- 正确写法:嵌套两次 LATERAL VIEW
SELECT outer_item, inner_item
FROM t
LATERAL VIEW explode(nested_array) AS inner_array
LATERAL VIEW explode(inner_array) AS inner_item;

explode 与 GROUP BY 混用

-- 错误写法:explode 的结果不能直接参与聚合
SELECT count(*), explode(items) FROM orders;
-- 报错

-- 正确写法:先 LATERAL VIEW 展开,再聚合
SELECT item, count(*) AS cnt
FROM orders
LATERAL VIEW explode(items) AS item
GROUP BY item;
📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看