Hive零基础从入门到实战 进阶篇(十一) HiveQL:列转行函数

目录

 

前言

1. 什么是列转行

2. 涉及函数

2.1 concat_ws(string SEP, array)

2.2 collect_set(col)

2.3 collect_list(col)

3. 列转行举例

3.1 去重列转行

3.2 不去重列转行


 

前言

本文来介绍,在Hive中如何实现列转行的操作。

 

1. 什么是列转行

假设Hive表中有两列数据,数据形式如下:

a 1
a 2
a 3
a 3
b 4
b 5
b 6
b 6

现希望将展现形式改为下面这种,依旧是两列数据,但第二列数据 将a、b所对应的一列所有数字都分别放到了一行数据中,并以逗号等指定分隔符分隔。

a 1,2,3,3
b 4,5,6,6

或者将展现形式改为下面这种,将原本第二列里的每个数据单独转为一列。

a 1 2 3 3
b 4 5 6 6

这两种操作就叫做列转行。

 

2. 涉及函数

在Hive中,并没有一个函数可以直接实现列转行的操作,需要使用两个或三个函数进行嵌套才能达成,涉及下表的几个函数,split在进阶篇(二)中已有介绍,这里着重介绍下另外三个函数。

返回数值类型 函数名\所需参数\参数数据类型 描述

string

concat_ws(string SEP, array)

拼接Array中的元素并用指定分隔符进行分隔

array

collect_set(col)

返回消除了重复元素的数组

array

collect_list(col)

返回允许重复元素的数组

2.1 concat_ws(string SEP, array)

功能:字符串连接函数,之前在进阶篇(二)中介绍过一种它的常用语法,这里介绍一种新的语法,在第二个参数位置传入一个元素数据格式为string的数组,将数组中的元素使用第一个参数传入的指定分隔符进行连接。

举例:

hive (app)> select concat_ws('-',array('a','b'));

a-b

2.2 collect_set(col)

功能:将该列中的所有元素去重后以数组的形式返回

举例:
新建test.txt文件,输入上文的两列数据,以逗号分隔

[root@hadoop ~]# vim test.txt

a,1
a,2
a,3
a,3
b,4
b,5
b,6
b,6

在hive中新建表temp_test5,将test文件中的数据插入,查看数据

CREATE TABLE temp_test5 (
      shop STRING
      ,shangpin_num INT
      ) row format delimited fields terminated BY ',';


load data local inpath '/root/test.txt' into table temp_test5;

select * from temp_test5;

temp_test5.shop	temp_test5.shangpin_num
a	1
a	2
a	3
a	3
b	4
b	5
b	6
b	6

使用collect_set,可以看到collect_set为聚合函数,配合group by,将shangpin_num中的元素去重后以数组的形式返回:

SELECT shop
      ,collect_set(shangpin_num)
FROM temp_test5
GROUP BY shop;

shop	_c1
a	[1,2,3]
b	[4,5,6]

2.3 collect_list(col)

功能:将该列中的所有元素以数组的形式返回,与collect_set的唯一区别是不会进行去重

举例:

SELECT shop
      ,collect_list(shangpin_num)
FROM temp_test5
GROUP BY shop;

shop	_c1
a	[1,2,3,3]
b	[4,5,6,6]

 

3. 列转行举例

collect_set和collect_list返回的是一个数组,而concat_ws的第二个输入参数也正好要求是数组。看到这里,大家可能已经很清楚如何组合函数进行列转行操作了,不过还是给大家演示一下~

 

3.1 去重列转行

注意:如果collect_set和collect_list中的列数据格式必须为string格式,否则报错如下:

hive (app)> SELECT shop
          >       ,concat_ws('-',collect_list(shangpin_num))
          > FROM temp_test5
          > GROUP BY shop;
FAILED: SemanticException [Error 10016]: Line 2:21 Argument type mismatch 'shangpin_num': Argument 2 of function CONCAT_WS must be "string or array", but "array" was found.

这里使用cast函数进行格式转换,concat_ws的第一个参数是分隔符,大家看自己需求使用:

SELECT shop
      ,concat_ws('-',collect_set(cast(shangpin_num as string)))
FROM temp_test5
GROUP BY shop;

shop	_c1
a	1-2-3
b	4-5-6

如果想将shangpin_num中去重后的元素各自作为一列,直接使用数组的下标将其分别取出即可:

SELECT shop
      ,collect_set(shangpin_num)[0]
      ,collect_set(shangpin_num)[1]
      ,collect_set(shangpin_num)[2]
FROM temp_test5
GROUP BY shop;

shop	_c1	_c2	_c3
a	1	2	3
b	4	5	6

 

3.2 不去重列转行

想要实现不去重列转行,将collect_set换为collect_list即可:

SELECT shop
      ,concat_ws('-',collect_list(cast(shangpin_num as string)))
FROM temp_test5
GROUP BY shop;

shop	_c1
a	1-2-3-3
b	4-5-6-6

如果想将shangpin_num中所有的元素各自作为一列,同理,直接使用数组的下标将其分别取出即可:

SELECT shop
      ,collect_list(shangpin_num)[0]
      ,collect_list(shangpin_num)[1]
      ,collect_list(shangpin_num)[2]
      ,collect_list(shangpin_num)[3]
FROM temp_test5
GROUP BY shop;

shop	_c1	_c2	_c3	_c4
a	1	2	3	3
b	4	5	6	6

 


能看到这里的同学,就右上角点个赞吧,3Q~

你可能感兴趣的:(Hive零基础从入门到实战 进阶篇(十一) HiveQL:列转行函数)