在 Spark 或 Hive 中,我们可以使用 LATERAL VIEW + EXPLODE 或 POSEXPLODE 将 array 或者 map 里面的数据由行转成列,这个操作在数据分析里面很常见。比如我们有以下表:
CREATE TABLE `default`.`iteblog_explode` ( `id` INT, `items` ARRAY<STRING>)
表里面的数据如下:
spark-sql> SELECT * FROM iteblog_explode; 1 ["iteblog.com","www.iteblog.com"]
我们想将 items 里面的数据转成一行一行,然后和其他表进行关联,这时候我们可以使用如下 SQL 实现:
spark-sql> select id, item from iteblog_explode LATERAL VIEW explode(items) tmpTable as item; 1 iteblog.com 1 www.iteblog.com
可见,我们把 items 里面的数据展开成一行一行了。如果我们还想得到每个元数在 array 的位置,那么可以使用 posexplode,具体如下:
spark-sql> select id, pos, item from iteblog_explode LATERAL VIEW posexplode(items) tmpTable as pos, item; 1 0 iteblog.com 1 1 www.iteblog.com
但是,如果你使用的是 Presto 或者 Trino,是没法使用 LATERAL VIEW 的,因为里面没有这个用法。不过我们可以使用 CROSS JOIN + UNNEST() 来实现同样的功能。具体如下:
presto> select id, pos, item from default.iteblog_explode CROSS JOIN UNNEST(items) WITH ORDINALITY AS temTable (item, pos); id | pos | item ----+-----+----------------- 1 | 1 | iteblog.com 1 | 2 | www.iteblog.com (2 rows)
可见,这个实现了 Spark 里面的 LATERAL VIEW posexplode 同样的功能,有一点区别是 Presto 里面的下标是从1开始的。当然,WITH ORDINALITY
是可选的,如果不加的话就相当于 LATERAL VIEW + EXPLODE,如下:
presto> select id,item from default.iteblog_explode CROSS JOIN UNNEST(items) AS temTable (item); id | item ----+----------------- 1 | iteblog.com 1 | www.iteblog.com (2 rows)
UNNEST 同样支持类型为 MAP 的列,这时候使用如下:
presto> select id,key,value from default.iteblog_explode CROSS JOIN UNNEST(map_col) AS temTable (key, value);本博客文章除特别声明,全部都是原创!
原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
本文链接: 【Presto 里面如何把 array 或 Map 里面的元素由行转成列】(https://www.iteblog.com/archives/10191.html)