Hive应用:explode和lateral view

本文介绍Hive中explode和lateralview函数的应用,通过案例解析如何利用这些函数处理复杂数据类型,如将map类型数据展开并与其他字段关联。

Hive应用:explode和lateral view

一、explode()

这个函数大多数人都接触过,将一行数据转换成列数据,可以用于array和map类型的数据。

用于array的语法如下:

select explode(arraycol) as newcol from tablename;
  • explode():函数中的参数传入的是arrary数据类型的列名。
  • newcol:是给转换成的列命名一个新的名字,用于代表转换之后的列名。
  • tablename:原表名。

用于map的语法如下:

select explode(mapcol) as (keyname,valuename) from tablename;
  • explode():函数中的参数传入的是map数据类型的列名。
  • 由于map是kay-value结构的,所以它在转换的时候会转换成两列,一列是kay转换而成的,一列是value转换而成的。
  • keyname:表示key转换成的列名称,用于代表key转换之后的列名。
  • valuename:表示value转换成的列名称,用于代表value转换之后的列名称。

注意:这两个值需要在as之后用括号括起来然后以逗号分隔。

以上为explode()函数的用法,此函数存在局限性:

  • 其一:不能关联原有的表中的其他字段。
  • 其二:不能与group by、cluster by、distribute by、sort by联用。
  • 其三:不能进行UDTF嵌套。
  • 其四:不允许选择其他表达式。

二、lateral view

lateral view是Hive中提供给UDTF的结合,它可以解决UDTF不能添加额外的select列的问题。

lateral view其实就是用来和想类似explode这种UDTF函数联用的,lateral view会将UDTF生成的结果放到一个虚拟表中,然后这个虚拟表会和输入行进行join来达到连接UDTF外的select字段的目的。

格式一

lateral view udtf(expression) tableAlias as columnAlias (,columnAlias)*
  • lateral view在UDTF前使用,表示连接UDTF所分裂的字段。
  • UDTF(expression):使用的UDTF函数,例如explode()。
  • tableAlias:表示UDTF函数转换的虚拟表的名称。
  • columnAlias:表示虚拟表的虚拟字段名称,如果分裂之后有一个列,则写一个即可;如果分裂之后有多个列,按照列的顺序在括号中声明所有虚拟列名,以逗号隔开。

格式二

from basetable (lateral view)*
  • 在from子句中使用,一般和格式一搭配使用,这个格式只是说明了lateral view的使用位置。
  • from子句后面也可以跟多个lateral view语句,使用空格间隔就可以了。

格式三

from basetable (lateral view outer)*

它比格式二只是多了一个outer,这个outer的作用是在UDTF转换列的时候将其中的空也给展示出来,UDTF默认是忽略输出空的,加上outer之后,会将空也输出,显示为NULL。这个功能是在Hive0.12是开始支持的。

三、案例

下面来说一个需求案例。

1、需求

有一张hive表,分别是学生姓名name(string),学生成绩score(map<string,string>),成绩列中key是学科名称,value是对应学科分数,请用一个hql求一下每个学生成绩最好的学科及分数、最差的学科及分数、平均分数。

表数据如下:

zhangsan|Chinese:80,Math:60,English:90
lisi|Chinese:90,Math:80,English:70
wangwu|Chinese:88,Math:90,English:96
maliu|Chinese:99,Math:65,English:60

2、准备

下面来做一下准备工作,创建表,并将数据导入表中,操作如下:

创建表:

create table student_score(name string,score map<String,string>)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':';

导入数据:

load data local inpath '/home/test/score' overwrite into table student_score;

检查一下数据,如下图:

确认数据导入没有问题。

3、分析

首先要处理这个表中的数据,本人第一想法是想找一下Hive有没有内置的操作map复杂类型的函数,可惜看了一遍,没有找到,这个思路只能放弃。

第二想法,是将map中的数据转换成一个虚拟表,然后与name字段关联,这样形成一张可操作的虚拟表。在查阅了资料之后,看到explode()函数可以做这个事情,首先写了一条语句:

select explode(score) from student_score;
select explode(score) as (key,value) from student_score;

结果:

此函数验证了它却是可以做到分离map的功能,将行转为列,难么既然行转了列,那么只需要将name字段关联上,就可以进行统计操作了。

可惜的是,explode函数怎么使用,都关联不了name字段。

既然Hive有这些东西,肯定能够做到关联其他字段的,这是本人作为一个程序员的信念,如果没有的话,这个功能做出来就是鸡肋了,只有关联了其他可以确定其为唯一消息的字段,这样的功能才又意义。

又在网上查询到,经常和explode函数和用的就是lateral view函数,那么这两个结合就能做到关联其他字段。写法如下:

select name,key,value from student_score
lateral view explode(score) scntable as key,value;

结果如下:

看到上面的数据,就是我们想要的结果,产生了这样一个虚拟表之后,所有的工作都变的简单了起来。

从上面两条语句可以看出,explode在select句中和在from子句中给虚拟字段命名的格式稍微有些差别,select句中需要加括号,from子句中不需要括号。

以上是这个需求的难点,其他的就不在做过多的说明。

4、结果

下面将结果抛出来,这可能不是最优的,但是是一种方式:

select sname,gk,gv,bk,bv,av from (
select * from (
select C.name as sname,C.key as gk,C.value as gv from (
select name,max(value) as gv from (
select name,key,value from student_score
lateral view explode(score) scnTable as key,value) as A
group by name) as B
left join
(select name,key,value from student_score
lateral view explode(score) scnTable as key,value) as C
on B.name=C.name and B.gv=C.value) as GG
left join
(select C.name as bname,C.key as bk,C.value as bv from
(select name,min(value) as bv from (
select name,key,value from student_score
lateral view explode(score) scnTable as key,value) as A
group by name) as B
left join
(select name,key,value from student_score
lateral view explode(score) snTable as key,value) as C
on B.name=C.name and B.bv=C.value) as BB
on GG.sname=BB.bname) as SS
left join
(select name as aname,avg(value) as av from (
select name,key,value from student_score
lateral view explode(score) scnTable as key,value) as A 
group by name) AA
on SS.sname=AA.aname

结果如下:

列名依次为:姓名、最好成绩的科目、分数、最差成绩的科目、分数、平均分

这里需要说一些,Hive中的基本数据类型,string类型应该是使用的自动转换机制,转换为了int,这里将score map<string,string>声明为score map<string,int>也是可以的。

四、测试

本人的hive环境为1.1.0CDH5版,此时将上面的数据做一下修改,来测试一下outer的作用,数据如下:

zhangsan|Chinese:80,Math:60,English:90
lisi|Chinese:90,Math:80,English:70
wangwu|Chinese:88,Math:90,English:96
maliu|Chinese:99,Math:65,English:

将maliu的英语成绩给去掉,然后导入到表中。

在执行以下语句:

select explode(score) from student_score;

结果如下:

可以看到最后一个English的成绩没有显示任何东西,也就是被UDTF给忽略了。

下面使用lateral view看一下:

select name,key,value from student_score
lateral view explode(score) scntable as key,value;

结果如下:

最后加上outer在试一下:

select name,key,value from student_score lateral view outer explode(score) scntable as key,value;

结果如下:

结果和没加outer是一样的,这就又是一个新的问题了,outer是否只对arrary类型的有效,对map类型无效呢?

本人又将arrary类型进行了测试,和map同样,都是什么都不显示,只是将没有的一列做了联表匹配。

这个问题有待研究。

上一篇:Hive语法:union

下一篇:

转载于:https://my.oschina.net/u/3754001/blog/3028523

### 回答1: Hive 中的 lateral view explode 是用来将一个表中的一列数组类型的数据拆分成多行,每一行对应数组中的一个元素。这样可以方便地对数组中的元素进行计算分析。使用方法如下: ``` SELECT ... FROM table_name LATERAL VIEW explode(array_column_name) exploded_table_alias AS column_alias ``` 其中 array_column_name 是数组类型的列名,exploded_table_alias 是拆分后的表的别名,column_alias 是拆分后新增的列的别名。 ### 回答2: Hive Lateral View ExplodeHive 的一种语法,可以将数组或者 Map 类型的列,展开成多行数据。Lateral View 关键字是用来处理嵌套类型的数据,而 Explode 函数可以将数组或 Map 类型的列展开成多行数据,每一行包含一组键值对或值。这个语法语句会将每个数组或 Map 对象分解成独立的行,其中包含了键值。这样对于数组或 Map 中的数据就可以进行分组、过滤、排序等操作,这种方式可以方便的处理多类型数据。 它的基本语法如下: select a.id, b.device_name from user_info a lateral view explode(a.devices) b as device_name; 这个语句的主要作用是将 user_info 表中的 devices 列展开成多行数据,每行数据包含一个用户设备名称设备id。此时,可以通过 device_name 字段来分组、过滤、聚合等操作,从而方便地对数据进行处理。Lateral View Explode 结合使用,可以方便的处理复杂数据类型,挖掘数据更深层次的信息,使数据分析更加高效、方便、精准。 总的来说,Hive Lateral View Explode 能够方便地将数组或 Map 类型的列进行展开,使得数据处理更加方便高效。使用它可以应对各种统计需求,分析更加深入有效。同时也要注意到 Lateral View Explode 这种语法可能会影响计算效率,因此在实际的使用中需要仔细设计优化查询语句,以提高计算效率。 ### 回答3: Hive Lateral View Explode 是在 Hive 中用于将一个数组或 Map 字段转换为行的扩展函数。它通过创建新行来展开数组或 Map 字段中的每个元素,以便更容易地进行查询分析。 在 Hive 中,数组 Map 字段是常见的数据类型,用于存储多个值或键值对。但是,这些类型常常难以查询分析,因为它们不能直接展开成一些行。Lateral View Explode 解决了这个问题。它允许将数组 Map 字段展开成多行,这样就可以更轻松地进行分析查询。 使用 Lateral View Explode 函数,可以将数组字段展开成多行,每行包含数组中的一个元素。例如,假设有一个包含成绩的数组字段 grades,它包含多个数字。使用 Lateral View Explode 函数,可以将 grades 字段展开成新的一组行,每一行包含一个成绩。 另外,Lateral View Explode 也可用于 Map 字段,使每个键值对都展开成一行。Lateral View Explode 还可以与其他 Hive 函数结合使用,以进一步扩展查询。 总之,Lateral View ExplodeHive 中一个重要的扩展函数,它可将数组 Map 字段转换成行,方便查询分析。使用 Lateral View Explode 函数可以大大简化数据分析的过程,提高查询效率,并使数据更加有用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值