当前位置:   article > 正文

Hive中行列转换详解_hive的行列转换

hive的行列转换

Hive中行列转换详解


1 行转列

1.1 多行转多列

数据表 row2col

col1   col2    col3
a      c       1
a      d       2
a      e       3  
b      c       4
b      d       5
b      e       6

现在要将其转化为:
col1   c      d      e
a      1      2      3
b      4      5      6

此时需要使用到max(case … when … thenelse 0 end),仅限于转化的字段为数值类型且为正值的情况
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

创建表:

create table row2col(col1 string,col2 string,col3 int)
row format delimited
fields terminated by ',';
  • 1
  • 2
  • 3

加载数据:

load data local inpath '/root/hivedata/row2col.txt' into table row2col;
  • 1
a,c,1
a,d,2
a,e,3
b,c,4
b,d,5
b,e,6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
select col1,
max(case col2 when 'c' then col3 else 0 end) as c,
max(case col2 when 'd' then col3 else 0 end) as d,
max(case col2 when 'e' then col3 else 0 end) as e
from row2col
group by col1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.2 多行转单列(重要)

需求

数据表 row2col_1
col1    col2    col3
a       b       1
a       b       2
a       b       3
c       d       4
c       d       5
c       d       6

将其转化为:
col1    col2    col3
a       b       1-2-3
c       d       4-5-6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

此时需要两个内置的函数:

concat_ws(参数1,参数2)用于进行字符的拼接参数1—指定分隔符
参数2—拼接的内容
collect_set(col3)它的主要作用是将某字段的值进行去重汇总产生array类型字段
如果不想去重可用collect_list()

创建原始表:

create table row2col_1(col1 string,col2 string,col3 int)
row format delimited
fields terminated by '\t';
  • 1
  • 2
  • 3

加载数据:

load data local inpath '/root/hivedata/row2col_1.txt' into table row2col_1;
  • 1
a	b	1
a	b	2
a	b	3
c	d	4
c	d	5
c	d	6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

思路

--需要一个收集多行数据的这么一个函数
		collect_set(col3),它的主要作用是将某字段的值进行去重汇总,产生 array 类
		型字段,如果不想去重可用 collect_list()。--set(去重)  list(重复)
	
--需要一个把收集的数据进行拼接函数
		concat(字段...)  栗子:select concat("wang","jie");
		concat_ws(参数 1,参数 2),用于进行字符的拼接
                参数 1—指定分隔符
                参数 2—拼接的内容 必须是String 或者是Array<String>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
--具体实现
select collect_set(col3) from row2col_1;
+----------------+--+
|      _c0       |
+----------------+--+
| [1,2,3,4,5,6]  |
+----------------+--+

--先分组再收集
select collect_set(col3) from row2col_1 group by col1,col2;
+----------+--+
|   _c0    |
+----------+--+
| [1,2,3]  |
| [4,5,6]  |
+----------+--+

select concat_ws("-",collect_set(col3)) from row2col_1 group by col1,col2;
--执行报错
 Argument 2 of function CONCAT_WS must be "string or array<string>", but "array<int>" was found.
 
--hive中如何实现类型转换呢? hive内置了一个函数cast 专门用于类型转换
select cast(3 as double);

--最终sql如下
select col1,col2,concat_ws("-",collect_set(cast(col3 as string))) from row2col_1 group by col1,col2;
+-------+-------+--------+--+
| col1  | col2  |  _c2   |
+-------+-------+--------+--+
| a     | b     | 1-2-3  |
| c     | d     | 4-5-6  |
+-------+-------+--------+--+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

2 列转行

2.1 多列转多行

数据表 col2row:

col1   c      d      e
a      1      2      3
b      4      5      6
  • 1
  • 2
  • 3

现要将其转化为:

  col1   col2    col3
  a      c       1
  a      d       2
  a      e       3
  b      c       4
  b      d       5
  b      e       6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里需要使用union进行拼接。
union 可以结合多个select语句 返回共同的结果集
保证每个select语句返回的数据类型个数是一致的。

创建表:

create table col2row(col1 string,c int,d int,e int)
row format delimited
fields terminated by ',';
  • 1
  • 2
  • 3

加载数据:

load data local inpath '/root/hivedata/col2row.txt' into table col2row;
  • 1
  a,1,2,3
  b,4,5,6
  • 1
  • 2
select col1, 'c' as col2, c as col3 from col2row
UNION
select col1, 'd' as col2, d as col3 from col2row
UNION
select col1, 'e' as col2, e as col3 from col2row
order by col1, col2;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.2 单列转多行(重要)

需求

数据表 col2row_2
col1    col2    col3
a       b       1,2,3
c       d       4,5,6
  • 1
  • 2
  • 3
  • 4

现要将其转化为:

  col1    col2    col3
  a       b       1
  a       b       2
  a       b       3
  c       d       4
  c       d       5
  c       d       6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里需要使用UDTF(表生成函数)explode(),该函数接受array类型的参数,其作用恰好与collect_set相反,实现将array类型数据行转列。explode配合lateral view实现将某列数据拆分成多行。

数据表 col2row_2:
+-----------------+-----------------+-----------------+--+
| col2row_2.col1  | col2row_2.col2  | col2row_2.col3  |
+-----------------+-----------------+-----------------+--+
| a               | b               | 1,2,3           |
| c               | d               | 4,5,6           |
+-----------------+-----------------+-----------------+--+
现要将其转化为:
col1 col2 col3
a 		b 	1
a 		b 	2
a 		b 	3
c 		d	4
c 		d 	5
c 		d	6
----初始化动作
create table col2row_2(col1 string,col2 string,col3 string)
row format delimited
fields terminated by '\t';

--执行过程
--首先二话不说 我就想把第三个字段炸开。 注意explode接收的参数类型:arraty map
--但是第三个字段是string类型 不符合explode的参数类型  如何把string 变成array
select explode(split(col3,",")) from col2row_2;
+------+--+
| col  |
+------+--+
| 1    |
| 2    |
| 3    |
| 4    |
| 5    |
| 6    |
+------+--+

-配合lateral view语法 把explode炸开之后的结果和原表进行关联
select col2row_2.col1,col2row_2.col2,tmp_table.*  from col2row_2 lateral view explode(split(col3,",")) tmp_table;
+-----------------+-----------------+----------------+--+
| col2row_2.col1  | col2row_2.col2  | tmp_table.col  |
+-----------------+-----------------+----------------+--+
| a               | b               | 1              |
| a               | b               | 2              |
| a               | b               | 3              |
| c               | d               | 4              |
| c               | d               | 5              |
| c               | d               | 6              |
+-----------------+-----------------+----------------+--+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/433304
推荐阅读
相关标签
  

闽ICP备14008679号