Hive行列转换

1.多行转多列

在这里插入图片描述

姓名(name)学科(subject)成绩(score)
A语文70
A数学80
A英语90
B语文75
B数学85
B英语95

行列转换思路分析及实现

多行转多列
如果需要将上⾯的样例表转换为

姓名 | 语⽂成绩 | 数学成绩 | 英语成绩

这样的格式,就是 多行转多列

思路:
涉及到行转成列,肯定是会按照某⼀列或者某⼏列的值进⾏分组来压缩⾏数,所以会⽤到group by。
分组之后需要⽤到聚合函数,由于多列中的每列只关⼼⾃⼰对应的数据,所以要使⽤case语句进⾏选择,⾄于聚合函数,只要数据能保证唯一性,max、min、avg(数值类型)等都可以

样例SQL

select
  name
  ,max(case subject when '数学' then score else 0 end) math
  ,max(case subject when '英语' then score else 0 end) english
  ,max(case subject when '语文' then score else 0 end) chinese
from ts
group by name;

输出过程

namechinesemathenglish
Amax(70,0,0)max(80,0,0)max(90,0,0)
Bmax(75,0,0)max(85,0,0)max(95,0,0)

输出结果

namechinesemathenglish
A708090
B758595

2.多列转多行

在这里插入图片描述

将上⾯⾏转多列的结果再转回成原始表结构的过程,就是多列转⾏

思路
列转⾏,会涉及到⾏数的增加,所以会⽤到UDTF(一进多出),⽽UDTF只是针对某⼀列的,要把这列扩展后⽣成的多⾏数据和源表中的各列拼接在⼀起,需要⽤到lateral view语法;
需要将多列⾥各列的列名(业务含义),在新数据中当做⼀个标识列,⽽与lateral view联合使⽤的explode函数是⽀持Map类型的,所以要先将原表⾥的多列变换成Map类型的⼀列,然后再⽤lateral view拆开。

样例SQL

select name,subject,score from 
(
select name,map('语文',chinese,'数学',math,'英语',english) scores from 
(select
  name
  ,max(case subject when '语文' then score else 0 end) chinese
  ,max(case subject when '数学' then score else 0 end) math
  ,max(case subject when '英语' then score else 0 end) english
from ts
group by name)ts1
)ts2
lateral view explode(scores) ts3 as subject,score

ts1

namechinesemathenglish
A708090
B758595

ts2

namescores
A{“语文”:“70”,“数学”:“80”,“英语”:“90”}
B{“语文”:“75”,“数学”:“85”,“英语”:“95”}

select explode(scores) from ts2;

keyvalue
语文70
数学80
英语90
语文75
数学85
英语95

输出结果

namesubjectscore
A语文70
A数学80
A英语90
B语文75
B数学85
B英语95

3.一列转一行

在这里插入图片描述

idnumname
1zs合肥
1ls南京
1ww杭州
1zl重庆
1sq郑州
2wb六安
2lq青岛
3dd三亚
3si常州
3sh武汉

SQL

select id,collect_list(name) names from ts group by id;

输出结果

idnames
3[“三亚”,“常州”,“武汉”]
1[“杭州”,“合肥”,“南京”,“郑州”,“重庆”]
2[“青岛”,“六安”]

SQL 外面套一层concat_ws(),输出以’,'分割的字符串

select id,concat_ws(',',collect_list(name)) names from ts group by id;

输出结果

idnames
3三亚,常州,武汉
1杭州,合肥,南京,郑州,重庆
2青岛,六安

4.一行转一列

在这里插入图片描述

idnames
3三亚,常州,武汉
1杭州,合肥,南京,郑州,重庆
2青岛,六安

SQL

select id,name from ts1
lateral view explode(split(names,',')) lateral_name as name

输出结果

idname
3三亚
3常州
3武汉
1杭州
1合肥
1南京
1郑州
1重庆
2青岛
2六安
  • 10
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值