lateral view explode 是什么?

lateral view explode(...)Hive SQL / Spark SQL 里常见的数组展开写法,用来把一行里的数组字段拆成多行。
常见形式:

select
  t.id,
  item
from demo_table t
lateral view explode(t.items) tmp as item;

这里的 items 是原表里的数组字段,explode(items) 会把数组里的每个元素展开成一行。

为什么需要把数组拆成多行?

有些表的一列不是普通单值,而是一个数组。
例如:

id  items
1   [apple, banana, orange]
2   [milk, bread]

如果想按单个元素统计、过滤或判断,就需要先把数组展开。
展开后结果可以理解成:

id  item
1   apple
1   banana
1   orange
2   milk
2   bread

这样每个数组元素都会变成独立的一行,后续就可以正常 wheregroup bycount

lateral view 和 explode 分别做什么?

explode 是函数,负责把数组拆开。
lateral view 是 Hive/Spark SQL 的语法,负责把 explode 拆出来的结果接到原表旁边。

lateral view              Hive/Spark SQL 的展开语法
explode(items)            把数组 items 拆成多行
tmp                       展开结果的临时表别名
item                      展开后的单个元素字段名

所以这句:

lateral view explode(t.items) tmp as item

可以理解成:把 t.items 这个数组拆开,拆出来的每个元素叫 item

一个完整例子

假设有一张表:

student_id  courses
1           [math, english]
2           [history, physics]

展开 SQL:

select
  student_id,
  course
from student_table
lateral view explode(courses) tmp as course;

结果:

student_id  course
1           math
1           english
2           history
2           physics

这时如果想统计每门课出现了多少次,就可以继续写:

select
  course,
  count(*) as cnt
from student_table
lateral view explode(courses) tmp as course
group by course;

它是标准 SQL 吗?

lateral view explode 不是所有数据库都通用的标准 SQL 写法,它主要出现在 Hive SQL / Spark SQL
其他数据库也有类似能力,但语法不同:

Hive / Spark SQL    lateral view explode(arr) t as item
PostgreSQL          cross join lateral unnest(arr) as item
BigQuery            cross join unnest(arr) as item
Presto / Trino      cross join unnest(arr) as t(item)
Snowflake           lateral flatten(input => arr)

MySQL 有类似写法吗?

MySQL 没有 lateral view explode(...)
如果 MySQL 8.0+ 里字段是 JSON 数组,可以用 JSON_TABLE 做类似展开:

select
  t.id,
  jt.item
from demo_table t
join json_table(
  t.items,
  '$[*]' columns (
    item varchar(100) path '$'
  )
) jt;

能力类似,语法不同。

容易混淆的点

lateral viewexplode 不是表字段,而是 SQL 语法和函数。
真正的字段一般是传给 explode 的那个列名,比如:

explode(items)

这里 items 才是表里的字段。

⚠️ 如果原字段不是数组类型,而只是普通字符串,explode 通常不能直接使用,需要先把字符串转成数组,或者用对应数据库支持的字符串拆分函数。


相关笔记

  • SQL
  • Hive
  • Spark SQL
  • MySQL