Hive 复杂数据类型

Hive 复杂数据类型有三种,分别是Array Map Struct

1、Array的使用

sql 复制代码
create table tableName(
......
colName array<基本类型>
......
)

说明:下标从0开始,越界不报错,以null代替

准备数据:

sql 复制代码
zhangsan	78,89,92,96
lisi	67,75,83,94
王五	23,12

这里得保证字段之间是制表符,然后数组之间是逗号

根据数据格式,新建对应的表:

sql 复制代码
create table db03.arr1(
  name string,
  scores array<int>
)
row format delimited
fields terminated by '\t'
collection items terminated by ',';

加载数据:

sql 复制代码
load data local inpath '/home/hivedata/arr1.txt' into table db03.arr1;
sql 复制代码
select * from db03.arr1;

需求1:查询每一个学生的第一个成绩

sql 复制代码
select name,scores[0] from arr1;

需求2:查询拥有三科成绩的学生的第二科成绩

sql 复制代码
select name,scores[1] from arr1 where size(scores) >=3;

需求3:查询所有学生的总成绩

sql 复制代码
select name,scores[0]+scores[1]+nvl(scores[2],0)+nvl(scores[3],0) from arr1;

需求4:查询每个人的最后一科的成绩

sql 复制代码
select name,scores[size(scores)-1] from arr1;

2、展开函数的使用 explode

为什么学这个,因为我们想把数据,变为如下格式:

sql 复制代码
zhangsan        78
zhangsan        89
zhangsan        92
zhangsan        96
lisi	67
lisi	75
lisi	83
lisi	94
王五	23
王五	12

explode 专门用于炸集合。

sql 复制代码
select explode(scores) from arr1;

col
78
89
92
96
67
75
83
94
23
12

这里我们想统计合计,结果这样写报错了

sql 复制代码
select name,explode(scores) from arr1

FAILED: SemanticException Error 10081: UDTF's are not supported outside the SELECT clause, nor nested in expressions

我们需要使用下面得方法进行计算合计

-- lateral view:虚拟表。

会将UDTF函数生成的结果放到一个虚拟表中,然后这个虚拟表会和输入行进行join来达到数据聚合的目的。

具体使用:

sql 复制代码
select name,cj from arr1 lateral view explode(scores) mytable as cj;

解释一下:

lateral view explode(scores) 形成一张虚拟的表,表名需要自己起

里面的列有几列,就起几个别名,其他的就跟正常的虚拟表一样了。

然后我们在计算每个人的总分

sql 复制代码
select name,sum(cj) 
from arr1 lateral view explode(scores) mytable as cj group by name;

等同于如下写法:
select name,sum(score) from
   (select name,score 
    from arr1 lateral view explode(scores) myscore as score 
) t group by name;

3、Map的使用

语法格式:

sql 复制代码
create table tableName(
.......
colName map<T,T>
......
)

上案例:

sql 复制代码
zhangsan	chinese:90,math:87,english:63,nature:76
lisi	chinese:60,math:30,english:78,nature:0
wangwu	chinese:89,math:25

建表:

sql 复制代码
create table db03.map1(
  name string,
  scores map<string,int>
)
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';

加载数据:

sql 复制代码
load data local inpath '/home/hivedata/map1.txt' into table db03.map1;

查看数据

sql 复制代码
select * from db03.map1;

需求1:查询数学大于35分的学生的英语和自然成绩

sql 复制代码
select name,scores['english'],scores['nature'] from map1
where scores['math'] > 35;

需求2 :查看每个人的前两科的成绩总和

sql 复制代码
select name,scores['chinese']+scores['math'] from map1;

需求3:将数据展示如下

-- 展开效果

zhangsan chinese 90

zhangsan math 87

zhangsan english 63

zhangsan nature 76

sql 复制代码
select name,subject,cj   
from map1 lateral view explode(scores) mytable as subject,cj ;

需求4:统计每个人的总成绩

sql 复制代码
select name,sum(cj)   
from map1 lateral view explode(scores) mytable as subject,cj  group by name;

假如根据总成绩降序排序
select name,sum(score) sumScore 
from map1 lateral view explode(scores) myscore as subject,score 
group by name order by sumScore desc;

子查询写法:
select name,sum(score) from (
    select name,subject,score from map1 lateral view explode(scores) mytable as subject,score
     ) a 
group by name;

需求5:行转列

sql 复制代码
-- 将下面的数据格式
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

新建表

sql 复制代码
create table map_temp as
select name,subject,cj   
from map1 lateral view explode(scores) mytable as subject,cj ;

先将学科和成绩形成一个kv对,其实就是字符串拼接

sql 复制代码
--使用concat函数,进行字符串拼接
select name,concat(subject,":",cj) from map_temp;
sql 复制代码
-- collect_set() 将分组的数据变成一个set集合。里面的元素是不可重复的。
select name,collect_set(concat(subject,":",cj)) from map_temp
group by name;
sql 复制代码
-- concat_ws(分隔符,集合) : 将集合中的所有元素通过分隔符变为字符串。
select name,concat_ws(",",collect_set(concat(subject,":",cj))) 
from map_temp group by name;
sql 复制代码
--将字符串变为map集合 使用一个函数 str_to_map
select name,str_to_map(concat_ws(",",collect_set(concat(subject,":",cj)))) 
from map_temp 
group by name;
相关推荐
爱吃面的猫3 小时前
大数据Hadoop之——集群环境搭建(了解)
大数据·hadoop·flume
roman_日积跬步-终至千里4 小时前
量化投研中的缓慢变化维:从因子定义到回测可复现的底层逻辑
大数据·数据仓库·金融
一路向北finish5 小时前
《Hadoop 高可用集群与 OpenStack Mitaka 控制节点部署全流程实操排坑指南》
大数据·linux·运维·服务器·hadoop·openstack
insertYam6 小时前
[hadoop高可用架构]
大数据·hadoop·架构
hopsky7 小时前
《Hive性能调优实战》核心内容详细解读
数据仓库·hive·hadoop
楠楠子呀2 天前
独立站聊天转化全链路:从二维码引流到数据复盘
java·javascript·数据仓库·python·c#·自动化·etl
-今昭-2 天前
Hadoop HDFS 高可用实战指南
运维·hadoop·hdfs·负载均衡
熊出没3 天前
AI经营分析数据中台如何搭建数仓
数据仓库
一路向北finish3 天前
《CentOS 7 搭建 Hadoop 3.3.6 分布式集群:NFS 共享方案完整实操》
linux·运维·hadoop·分布式·centos