Hive中的 explode / posexplode 和 lateral view

1. explode()

将 arrary 或 map 结构数据拆分成多行,并返回拆分后的每个元素。

1.1 用于 array 的语法如下
select explode(arraycol) as newcol from tablename;
  • explode ():函数中的参数传入的是 arrary 数据类型的列名
  • newcol:给转换后的列起一个新的名字,用于代表转换之后默认的列名
  • tablename:原表名
-- data表 源数据

id   |   names
---------------
1    |   ["Alice", "Bob"]
2    |   ["Charlie", "Dave", "Eve"]

-- 使用explode函数拆分names列

SELECT explode(names) AS name
FROM data;

-- 输出结果

name
--------
Alice
Bob
Charlie
Dave
Eve
1.2 用于 map 的语法如下
select explode(mapcol) as (keyname,valuename) from tablename;
  • explode ():函数中的参数传入的是 map 数据类型的列名
  • 由于 map 是 kay-value 结构,所以在转换的时候会转换成两列,一列是 key 转换而成的,一列是 value 转换而成的
  • keyname:表示 key 转换成的列名称,用于代表 key 转换之后默认的列名
  • valuename:表示 value 转换成的列名称,用于代表 value 转换之后默认的列名

注意:这两个值需要在 as 之后用括号括起来然后以逗号分隔。

-- 源数据

id   |   info
---------------
1    |   {"name":"Alice", "age":25}
2    |   {"name":"Bob", "age":30, "gender":"Male"}

-- 使用explode(map)函数拆分info列

select explode(info) as (kkk, vvv)
from data;

-- 输出结果

   kkk     |   vvv
--------------------
   name    |   Alice
   age     |   25
   name    |   Bob
   age     |   30
   gender  |   Male
1.3 explode() 函数存在的局限性
  • 不能关联原有的表中的其他字段
  • 不能与 group by、cluster by、distribute by、sort by 联用
  • 不能进行 UDTF 嵌套
  • 不允许选择其他表达式(不要理解)
2. posexplode()

将 arrary 数据(不能用于map数据)拆分成多行,并返回拆分后的 行索引对应的 arrary 元素

用于 array 的语法如下
select posexplode(arraycol) as newcol from tablename;
  • posexplode ():函数中的参数传入的是 arrary 数据类型的列名
  • newcol:给转换后的列起一个新的名字,用于代表转换之后默认的列名
  • tablename:原表名
-- data表 源数据

id   |   names
---------------
1    |   ["Alice", "Bob"]
2    |   ["Charlie", "Dave", "Eve"]

-- 使用posexplode函数拆分names列

SELECT posexplode(names) AS (pos, name)
FROM data;

-- 输出结果

  pos   |   name
----------------
  0     |   Alice
  1     |   Bob
  0     |   Charlie
  1     |   Dave
  2     |   Eve
3. lateral view

lateral view 是 Hive 中提供给 UDTF 函数使用的,它可以解决使用 UDTF 后不能添加额外 select 列的问题。

lateral view 会将 UDTF 生成的结果放到一个虚拟表中,然后这个虚拟表会和 输入行 进行 join 来达到关联 UDTF 外的 select 字段的目的。

-- 语法

lateral view udtf(expression) tableAlias as columnAlias (,columnAlias)*
  • tableAlias:表示 UDTF 函数转换的虚拟表的名称
  • columnAlias:表示虚拟表的虚拟字段名称,如果分裂之后有一个列,则写一个即可;如果分裂之后有多个列,按照列的顺序声明所有虚拟列名,以逗号隔开。
3.1 用于 explode(array)
-- data表 源数据

id   |   names
---------------
1    |   ["Alice", "Bob"]
2    |   ["Charlie", "Dave", "Eve"]

-- 使用explode函数拆分names列,并查询出 id列

SELECT id, name
FROM data
lateral view explode(names) tmp as name;

-- 输出结果

id   |   name
--------------
1    |   Alice
1    |   Bob
2    |   Charlie
2    |   Dave
2    |   Eve
3.2 用于 explode(map)
-- data表 源数据

id   |   info
---------------
1    |   {"name":"Alice", "age":25}
2    |   {"name":"Bob", "age":30, "gender":"Male"}

-- 使用explode(map)函数拆分info列,并查询出 id列

SELECT id, key, value
FROM data
LATERAL VIEW explode(info) tmp AS key, value;

-- 输出结果

id   |   key     |   value
--------------------------
1    |   name    |   Alice
1    |   age     |   25
2    |   name    |   Bob
2    |   age     |   30
2    |   gender  |   Male
3.3 用于 posexplode(array)
-- data表 源数据

id   |   names
---------------
1    |   ["Alice", "Bob"]
2    |   ["Charlie", "Dave", "Eve"]

-- 使用posexplode函数拆分names列

SELECT id, pos, name
FROM data
LATERAL VIEW posexplode(names) tmp AS pos, name;

-- 输出结果

id  |  pos   |   name
----------------------
1   |   0    |   Alice
1   |   1    |   Bob
2   |   0    |   Charlie
2   |   1    |   Dave
2   |   2    |   Eve
学习链接

Hive 应用:explode 和 lateral view

Logo

大数据从业者之家,一起探索大数据的无限可能!

更多推荐