Hive 复杂数据类型之map

定义格式如下:

create table tableName(
.......
colName map<T,T>
......
)

案例准备:

测试数据如下

zhangsan	chinese:90,math:87,english:63,nature:76
lisi	chinese:60,math:30,english:78,nature:0
wangwu	chinese:89,math:25
create table if not exists map1(
    name string,
    score map<string,int>
)
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';
load data local inpath '/data/map1.txt' into table map1;
select *
from map1;

结果如下,可以看出,map整体用{}包裹

+--------+-------------------------------------------------+
|name    |score                                            |
+--------+-------------------------------------------------+
|zhangsan|{"chinese":90,"math":87,"english":63,"nature":76}|
|lisi    |{"chinese":60,"math":30,"english":78,"nature":0} |
|wangwu  |{"chinese":89,"math":25}                         |
+--------+-------------------------------------------------+

查询语句:

--查询数学大于35分的学生的英语和自然成绩:
select m.name,m.score['english'] english, m.score['nature'] nature
from map1 m
where m.score['math']>35;

+--------+-------+------+
|name    |english|nature|
+--------+-------+------+
|zhangsan|63     |76    |
+--------+-------+------+


--查看每个人的前两科的成绩总和
select  m.name,m.score['chinese']+m.score['math'] from map1 m;
+--------+---+
|name    |c1 |
+--------+---+
|zhangsan|177|
|lisi    |90 |
|wangwu  |114|
+--------+---+

展开查询

- 展开效果
zhangsan	chinese		90
zhangsan	math	87
zhangsan	english 	63
zhangsan	nature		76

map类型的也可以用explode展开

select explode(score) as (m_subject,m_score) from map1;
+---------+-------+
|m_subject|m_score|
+---------+-------+
|chinese  |90     |
|math     |87     |
|english  |63     |
|nature   |76     |
|chinese  |60     |
|math     |30     |
|english  |78     |
|nature   |0      |
|chinese  |89     |
|math     |25     |
+---------+-------+
-- 使用lateral view explode 结合查询:
select name, m_subject, m_score
from map1 lateral view explode(score) subview as
         m_subject, m_score;
+--------+---------+-------+
|name    |m_subject|m_score|
+--------+---------+-------+
|zhangsan|chinese  |90     |
|zhangsan|math     |87     |
|zhangsan|english  |63     |
|zhangsan|nature   |76     |
|lisi    |chinese  |60     |
|lisi    |math     |30     |
|lisi    |english  |78     |
|lisi    |nature   |0      |
|wangwu  |chinese  |89     |
|wangwu  |math     |25     |
+--------+---------+-------+

- -统计每个人的总成绩
select name, sum(m_score)
from map1 lateral view explode(score) subview as
         m_subject, m_score
group by name;
+--------+---+
|name    |_c1|
+--------+---+
|lisi    |168|
|wangwu  |114|
|zhangsan|316|
+--------+---+

将数据动态写入map字段中

就是把上面的流程反过来

将下面的数据格式
zhangsan        chinese 90
zhangsan        math    87
zhangsan        english 63
zhangsan        nature  76
lisi    chinese 60
lisi    math    30
lisi    english 78
lisi    nature  0
wangwu  chinese 89
wangwu  math    25
wangwu  english 81
wangwu  nature  9
转成:
zhangsan chinese:90,math:87,english:63,nature:76
lisi chinese:60,math:30,english:78,nature:0
wangwu chinese:89,math:25,english:81,nature:9

准备数据

create table map_tmp as
select name, m_subject, m_score
from map1 lateral view explode(score) subview as
         m_subject, m_score;

开始写:

--第一步:将科目和成绩组合在一起,concat
select name,concat(m_subject,":",m_score) from map_tmp;
+--------+----------+
|name    |c1        |
+--------+----------+
|zhangsan|chinese:90|
|zhangsan|math:87   |
|zhangsan|english:63|
|zhangsan|nature:76 |
|lisi    |chinese:60|
|lisi    |math:30   |
|lisi    |english:78|
|lisi    |nature:0  |
|wangwu  |chinese:89|
|wangwu  |math:25   |
+--------+----------+


--第二步: 将所有属于同一个人的数据组合在一起
select name,collect_set(concat(m_subject,":",m_score)) from map_tmp
group by name;
+--------+-------------------------------------------------+
|name    |c1                                               |
+--------+-------------------------------------------------+
|lisi    |["chinese:60","math:30","english:78","nature:0"] |
|wangwu  |["chinese:89","math:25"]                         |
|zhangsan|["chinese:90","math:87","english:63","nature:76"]|
+--------+-------------------------------------------------+


--第三步:将数组变成一个字符串concat_ws
select name,concat_ws(",",collect_set(concat(m_subject,":",m_score))) from map_tmp
group by name;

+--------+---------------------------------------+
|name    |c1                                     |
+--------+---------------------------------------+
|lisi    |chinese:60,math:30,english:78,nature:0 |
|wangwu  |chinese:89,math:25                     |
|zhangsan|chinese:90,math:87,english:63,nature:76|
+--------+---------------------------------------+


--第四步:将字符串转成map 使用函数str_to_map(text, delimiter1, delimiter2)
--text:是字符串
--delimiter1:多个键值对之间的分隔符
--delimiter2:key和value之间的分隔符

select name,
       str_to_map(concat_ws(",",collect_set(concat(m_subject,":",m_score))),",",":")
       from map_tmp
group by name;
+--------+---------------------------------------------------------+
|name    |c1                                                       |
+--------+---------------------------------------------------------+
|lisi    |{"chinese":"60","math":"30","english":"78","nature":"0"} |
|wangwu  |{"chinese":"89","math":"25"}                             |
|zhangsan|{"chinese":"90","math":"87","english":"63","nature":"76"}|
+--------+---------------------------------------------------------+

--第五步:存储准备的表中
create table map2 as
select name,
       str_to_map(concat_ws(",",collect_set(concat(m_subject,":",m_score))),",",":")
       from map_tmp
group by name;

总结

  • hivemap类型创建时需要指定分隔符
 collection items terminated by ','
map keys terminated by ':';
  • map类型可以通过[]来取值
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值