Hive入门:一文读懂Hive的explode和 lateral view语法

1.概述
express

    lateral view用于和split, explode等UDTF一块儿使用,它可以将一行数据拆成多行数据,在此基础上能够对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分红一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。json


2.Explode语法数据结构

    上一篇文章咱们讲了:Hive实战:详解Hive复合数据类型;将一些如何在复合数据结构使用explode语法。ide


1).应用于array数据类型,直接查上篇文章的表student1函数


语法格式:spa

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


//student1表中数据:hive> select  * from student1;OK100  "student1"  [80.0,82.0,84.0]101  "student2"  [70.0,72.0,74.0]102  "student3"  [60.0,62.0,64.0]Time taken: 0.162 seconds, Fetched: 3 row(s)
// 在字段类型为array的字段score上应用explode语法:> select explode(score) as new_score from student1;OK80.082.084.070.072.074.060.062.064.0Time taken: 0.121 secondsFetched: 9 row(s)


2).应用于map数据类型,直接查上篇文章的表student2code

   

语法格式:
orm

select explode(mapcol) as (keyname,valuename) from tablename;  explode():函数中的参数传入的是map数据类型的列名。  因为map是kay-value结构的,因此它在转换的时候会转换成两列,一列是kay转换而成的,一列是value转换而成的。  keyname:表示key转换成的列名称,用于表明key转换以后的列名。  valuename:表示value转换成的列名称,用于表明value转换以后的列名称。
// student2表中数据:hive> select  * from student2;OK100  "student1"  {"\"yuwen\"":80.0,"\"shuxue\"":82.0,"\"yingyu\"":84.0}101  "student2"  {"\"yuwen\"":70.0,"\"shuxue\"":72.0,"\"yingyu\"":74.0}102  "student3"  {"\"yuwen\"":60.0,"\"shuxue\"":62.0,"\"yingyu\"":64.0}Time taken: 0.262 seconds, Fetched: 3 row(s)
// 在字段类型为array的字段score上应用explode语法:hive> select explode(score) as (score_key,score_value) from student2;OK"yuwen"  80.0"shuxue"  82.0"yingyu"  84.0"yuwen"  70.0"shuxue"  72.0"yingyu"  74.0"yuwen"  60.0"shuxue"  62.0"yingyu"  64.0Time taken: 0.153 seconds, Fetched: 9 row(s)

   

3)explode使用的局限性get


    a.不能关联原有的表中的其余字段。string

    b.不能与group by、cluster by、distribute by、sort by联用。

    c.不能进行UDTF嵌套。

    d.不容许选择其余表达式。


3.Lateral View语法


    因为explode的局限性,一般会与Lateral View结合使用,配合Explode(或者其余的UDTF),一个语句生成把单行数据拆解成多行后的数据结果集;Lateral view语法首先会将UDTF处理生成的结果放到一张虚拟表中,而后再将这个虚拟表和输入行进行关联实现添加列到select中。


1).单个Later View语法使用

    这里仍是拿上篇文章中的student2为例,字段id,name,score,其中score数据类型为Map<科目,分数>,可结合Later View语法查询出学生成绩:


    Explode与其余字段关联报错:

// Explode与其余字段关联报错:hive> select id,name,explode(score) as new_score from student1;FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions

    Explode结合Lateral view与其余字段关联

hive> select id,name,course,value from student2 lateral view explode(score) scoretable as course,value;OK100  "student1"  "yuwen"  80.0100  "student1"  "shuxue"  82.0100  "student1"  "yingyu"  84.0101  "student2"  "yuwen"  70.0101  "student2"  "shuxue"  72.0101  "student2"  "yingyu"  74.0102  "student3"  "yuwen"  60.0102  "student3"  "shuxue"  62.0102  "student3"  "yingyu"  64.0Time taken: 0.148 seconds, Fetched: 9 row(s)


2).多个Lateral View结合使用


    a.新建表student4,一共有四个字段id,name,score,score2,其中score公共基础课,数据类型为Map<科目,分数>,score2选修课,数据类型为Map<科目,分数>,建表语句:

hive> create table student4(id int,name string,score map<string,double>,score2 map<string,double>)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' COLLECTION ITEMS TERMINATED BY '|' MAP KEYS TERMINATED BY ':';OKTime taken: 0.221 seconds

    b.数据准备student4.txt:

[root@salver158 ~]# cat student4.txt 100,"student1","yuwen":80|"shuxue":82|"yingyu":84,"tiyu":86|"meishu":88101,"student2","yuwen":70|"shuxue":72|"yingyu":74,"tiyu":76|"meishu":76102,"student3","yuwen":60|"shuxue":62|"yingyu":64,"tiyu":68|"meishu":68

    c.加载数据:

hive> load  data local inpath "/root/student4.txt"  into  table student4;Loading data to table lujs.student4

    d.数据加载成功:

hive> select * from student4;OK100  "student1"  {"\"yuwen\"":80.0,"\"shuxue\"":82.0,"\"yingyu\"":84.0}  {"\"tiyu\"":86.0,"\"meishu\"":88.0}101  "student2"  {"\"yuwen\"":70.0,"\"shuxue\"":72.0,"\"yingyu\"":74.0}  {"\"tiyu\"":76.0,"\"meishu\"":76.0}102  "student3"  {"\"yuwen\"":60.0,"\"shuxue\"":62.0,"\"yingyu\"":64.0}  {"\"tiyu\"":68.0,"\"meishu\"":68.0}Time taken: 0.16 seconds, Fetched: 3 row(s)

    e.多个lateral view语句查询:

hive> select id,name,score_course,score_value,score2_course,score2_value from student4    >  lateral view explode(score) scoreTable1 as score_course,score_value    >  lateral view explode(score2) scoreTable2 as score2_course,score2_value;OK100  "student1"  "yuwen"  80.0  "tiyu"  86.0100  "student1"  "yuwen"  80.0  "meishu"  88.0100  "student1"  "shuxue"  82.0  "tiyu"  86.0100  "student1"  "shuxue"  82.0  "meishu"  88.0100  "student1"  "yingyu"  84.0  "tiyu"  86.0100  "student1"  "yingyu"  84.0  "meishu"  88.0101  "student2"  "yuwen"  70.0  "tiyu"  76.0101  "student2"  "yuwen"  70.0  "meishu"  76.0101  "student2"  "shuxue"  72.0  "tiyu"  76.0101  "student2"  "shuxue"  72.0  "meishu"  76.0101  "student2"  "yingyu"  74.0  "tiyu"  76.0101  "student2"  "yingyu"  74.0  "meishu"  76.0102  "student3"  "yuwen"  60.0  "tiyu"  68.0102  "student3"  "yuwen"  60.0  "meishu"  68.0102  "student3"  "shuxue"  62.0  "tiyu"  68.0102  "student3"  "shuxue"  62.0  "meishu"  68.0102  "student3"  "yingyu"  64.0  "tiyu"  68.0102  "student3"  "yingyu"  64.0  "meishu"  68.0Time taken: 0.188 seconds, Fetched: 18 row(s)



3.)lateral view解析Json,加入上面的表中score里面是放的一个json串,固然咱们能够用get_json_object处理,这里也能够用later view处理

    a.新建表student5,一共有3个字段id,name,score,其中score为string类型里面存的是json串,建表语句:

hive> create table student5(id int,name string,score string)ROW FORMAT DELIMITED FIELDS TERMINATED BY '|';

    b.数据准备student5.txt

[root@salver158 ~]# cat student4.txt 100,"student1","yuwen":80|"shuxue":82|"yingyu":84,"tiyu":86|"meishu":88101,"student2","yuwen":70|"shuxue":72|"yingyu":74,"tiyu":76|"meishu":76102,"student3","yuwen":60|"shuxue":62|"yingyu":64,"tiyu":68|"meishu":68

    c.加载数据到student5表中:

hive> load data local inpath '/root/student5.txt' into table student5;

    d.数据加载成功:

hive> select * from student5;OK100  student1  {"yuwen":80,"shuxue":81,"yingyu":82}101  student2  {"yuwen":70,"shuxue":71,"yingyu":72}102  student3  {"yuwen":60,"shuxue":61,"yingyu":62}Time taken: 0.092 seconds, Fetched: 3 row(s)

    e. 先用get_json_object解析json


hive> select id,name,get_json_object(score, '$.yuwen'),get_json_object(score, '$.shuxue'),get_json_object(score, '$.yingyu') from student5;OK100  student1  80  81  82101  student2  70  71  72102  student3  60  61  62Time taken: 0.161 seconds, Fetched: 3 row(s)

    f. 用lateral view解析json

hive> select * from student5     > lateral view json_tuple(score,'yuwen','shuxue','yingyu') state_json as yuwen,shuxue,yingyu;OK100  student1  {"yuwen":80,"shuxue":81,"yingyu":82}  80  81  82101  student2  {"yuwen":70,"shuxue":71,"yingyu":72}  70  71  72102  student3  {"yuwen":60,"shuxue":61,"yingyu":62}  60  61  62Time taken: 0.111 seconds, Fetched: 3 row(s)

    

    至此,Hive的explode和 lateral view语法介绍和使用讲解完毕,有兴趣本身去手动敲一遍试试吧!

相关文章
相关标签/搜索