Hive QL表函数和列转行

表函数

所谓表函数,指的是使用该函数可以将Hive复杂类型数据生成一个表。

Hive QL查询语言提供了以下几个表函数,分别解释如下。

explode()

该函数将hive的复杂数据类型拆分成多行。这是一个表生成函数,对于数组中每一个元素返回一行。返回类型是N行。

语法:explode(array a)

对于数组a中的每个元素,将生成一行且包含该元素。它有两个重载的方法,接收不同的参数:

  • explode(ARRAY):每行对应数组中的一个元素。
  • explode(MAP):每行对应每个map键-值,其中一个字段是map的键,另一个字段是map的值。

例如,将数组“'苹果','樱桃','火龙果'”拆成多行。

select explode(array('苹果','樱桃','火龙果'));

转换结果如下所示:

苹果
樱桃
火龙果

例如,将集合“map('服装',98,'图书',198,'玩具',78)”拆成多行。

select explode(map('服装',98,'图书',198,'玩具',78));

转换结果如下所示:

服装    98
图书    198
玩具    78

posexplode()

与explode()类似,不同的是还返回各元素在数组中的位置。

语法:posexplode (array)。注意,它只接收数组参数。

例如,将数组“'苹果','樱桃','火龙果'”拆成多行。

select posexplode(array('苹果','樱桃','火龙果'));

转换结果如下所示:

0       苹果
1       樱桃
2       火龙果

stack()

格式转化,把M列转换成n行,每行有M/n个字段,其中n必须是个常数。

语法:stack(INT n, v_1, v_2, ..., v_k)

例如,将下面的数据转换为两行:

'A',20,'b',date'2019-04-11','B',30,'c',date'2019-04-11'
select stack(2, 'A',20,'b',date'2019-04-11','B',30,'c',date'2019-04-11');

转换结果如下所示:

A       20      b       2019-04-11
B       30      c       2019-04-11

inline()

将结构体数组提取出来并插入到表中。

语法:inline(ARRAY)

例:

select inline(array(struct('a',20,date'2019-11-06'),struct('b',30,date'2019-11-16')));

转换结果如下所示:

a       20      2019-11-06
b       30      2019-11-16

【示例】使用HiveQL实现单词计数。

下面我们实现一个Hive版本的单词计数。说明,这仅是为了演示Hive的表函数使用。

假设我们现在有一个文本文件input.txt,其内容如下:

good good study
day day up

现在通过Hive来统计每个单词的词频。

1)首先创建存储字符串的表docs:

create table docs(line string);  

2)加载数据到Hive表中:

load data local inpath '/home/hduser/data/input.txt' overwrite into table docs;

3)查询每个单词的数量:

select word,count(1) as count 
from (select explode(split(line,' ')) as word from docs) w
group by word
order by word;

提示:

函数split(string str, string pat):按照正则表达式pat来分割字符串str,并将分割后的字符串以数组的形式返回,返回类型为Array。

保存结果:-- CTAS

create table wordcounts as
select word,count(1) as count 
from (select explode(split(line,' ')) as word from docs) w
group by word
order by word;

Lateral View

Lateral View用于和split、explode等表生成函数一起使用的,能将一行数据拆分成多行数据,在此基础上可以对拆分的数据进行聚合。

Lateral view首先为原始表的每行调用表生成函数,表函数会把一行拆分成一行或者多行。

Lateral View然后将结果输出行连接到输入行,以形成虚拟表(具有提供的表别名)。

【示例】列转行

原始表:

id     desc
001	书名: 追风筝的人, ISBN编号: 9787208061644, 作者: 卡勒德.胡赛尼
002	书名: 秘密花园, ISBN编号: 9787550252585, 作者: 乔汉娜·贝斯福

希望输出的形式:

001    书名: 追风筝的人
001    ISBN编号: 9787208061644
001     作者: 卡勒德.胡赛尼
002    书名: 秘密花园
002    ISBN编号: 9787550252585
002    作者: 乔汉娜·贝斯福

步骤:

1). 创建hive表

create table book(
   id string,
   book_desc string
) 
row format delimited 
fields terminated by '\t';

2). 将数据文件加载到表中

load data local inpath'/home/hduser/data/books.txt' into table book;

3). 查询

select explode(split(book_desc,',')) from book;

select id,sp 
from book lateral view explode(split(book_desc, ',')) t as sp;

《Spark原理深入与编程实战》