首页 / 数组和 Map
POSEXPLODE 带下标展开数组
POSEXPLODE 把数组展开成多行,同时输出元素在数组中的位置,位置从 0 开始。MaxCompute、Doris、Hive 和 Spark 支持;Hologres、StarRocks 和 Flink 的文档中没有带位置的展开函数,需要另行改写。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | POSEXPLODE(array) | 每个元素一行,两列分别是从 0 开始的下标和元素值。 | 官方文档 |
| Hologres | 不支持 | — | 数组函数文档中只有 UNNEST,没有同时返回位置的写法。 | 官方文档 |
| StarRocks | 不支持 | — | UNNEST 文档中没有返回元素位置的参数或 WITH ORDINALITY 写法。 | 官方文档 |
| Doris | 支持 | POSEXPLODE(array) | 配合 LATERAL VIEW 使用,返回包含位置和元素的 STRUCT,位置从 0 开始。数组为 NULL 或为空时不输出行;需要保留这类行时用 POSEXPLODE_OUTER。 | 官方文档 |
| Hive | 支持 | posexplode(ARRAY<T> a) | Hive 0.13.0 起提供。返回 pos 和 val 两列,pos 从 0 开始。 | 官方文档 |
| Spark SQL | 支持 | posexplode(expr) | Spark 2.0.0 起提供,也可以展开 Map,位置从 0 开始。 | 官方文档 |
| Flink SQL | 不支持 | — | 内置函数文档中没有 POSEXPLODE,也没有说明 UNNEST 支持 WITH ORDINALITY。 | 官方文档 |
迁移注意事项
- 位置从 0 开始。和 SPLIT_PART、数组下标等从 1 开始的写法混用时,容易差 1。
- Hologres、StarRocks 和 Flink 没有带位置的展开函数。如果只需要元素,改用 UNNEST;如果依赖位置,需要在入库前补充位置信息,或用其他方式改写。
- Doris 的 POSEXPLODE 在数组为 NULL 或为空时不输出行,会导致左表的行消失;需要保留时改用 POSEXPLODE_OUTER。
- Hive 和 Doris 需要写在 LATERAL VIEW 中,列别名的写法要按各自文档调整。
示例
展开商品列表并保留顺序
SELECT order_id, pos, item FROM orders LATERAL VIEW POSEXPLODE(items) t AS pos, item;SELECT order_id, pos, item FROM orders LATERAL VIEW POSEXPLODE(items) t AS pos, item;SELECT order_id, pos, item FROM orders LATERAL VIEW posexplode(items) t AS pos, item;SELECT order_id, pos, item FROM orders LATERAL VIEW posexplode(items) t AS pos, item;