1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Hive Hsql行转列 列转行实现

Hive Hsql行转列 列转行实现

时间:2024-06-03 18:58:19

相关推荐

Hive  Hsql行转列 列转行实现

HQL中实现行列转换

其实并不用纠结哪个是行转列、哪个是列转行,明白二者之间的需求即可

在Hive sql应用中会遇到“行转列”和“列转行”的场景,下面介绍其基本使用语法。

1.行转列:

关键字:collect_set() / collect_list()、concat_ws()

1)collect_set()/collect_list():

collect_set( )函数只接受基本数据类型,作用是对参数字段进行去重汇总,返回array类型字段;

collect_list()函数和collect_set( )作用一样,只是前者不去重,后者去重。

2)concat_ws():

concat_ws (separator,字符串A/字段名A,字符串B/字段名B…)是concat的特殊形式,第一个参数是分隔符,分隔符会放到要连接的字符串之间,分隔符可以是字符串,也可以是其他参数。如果分隔符为NULL,则结果为NULL,函数会忽略任何分隔符参数后的 NULL值。但是concat_ws( )不会忽略任何空字符串。(然而会忽略所有的 NULL),如果参数为string类型数组则合并数组内字符串。

例:concat_ws( ‘,’, [ ‘a ‘, ‘b’])–> ‘a,b’

行转列基本语法:

select 分类字段,concat_ws(’,’,collect_set(合并字段)) as 别名 from table_name group 分类字段;

/* 原始数据name gendertimes张三 男 唐李四 男 唐王五 男 明赵六 男 明*/-- 先用collect_set将列拼接在一起,然后再通过concat_ws进行展开拼接SELECT a.gender_times,concat_ws(';',collect_set(a.name)) nameFROM(SELECT name,concat(gender, '_','times') gender_timesFROM hero_info) tGROUP BY t.gender_times;/*查询结果gender_times name 男_唐张三;李四男_明王五;赵六

2.列转行

关键字:explode()、split()和LATERAL VIEW

split():

将一个字符串按照指定字符分割,结果为一个array;

2)explode():

将一列复杂的array或者map拆分为多行,它的参数必须为map或array;

3)lateral view:

lateral view udtf(字段名)表别名/表临时名as列别名/列临时名。lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分成一或者多行,lateralview再把结果组合,产生一个支持别名表的虚拟表。

列转行基本语法:

select 字段,字段别名 from table_name lateral view explode(split(拆分字段,分隔符))表别名 as 字段别名;

/*原始数据province city河南 郑州市,开封市,洛阳市河北 石家庄市,保定市湖南 长沙市,岳阳市,常德市*/-- addr为表名SELECT province,city_nFROM addr LATERAL VIEW explode (split(city,',')) addr_tmp AS city_n;/*-- 查询结果河南郑州市河南开封市河南洛阳市河北石家庄市河北保定市湖南长沙市湖南岳阳市湖南常德市*/

下面再用别的例子进行阐述一下

行转列

数据、建表如下:

张三 白羊座 A

李四 射手座 A

王五 白羊座 B

刘六 白羊座 A

诸葛七 射手座 A

小明 白羊座 B

create table person_info(name string,constellation string,blood_type string)row format delimited fields terminated by "\t";

需求如下:

把星座和血型一样的人归类到一起

射手座,A 大海|凤姐

白羊座,A 张三|刘六

白羊座,B 王五|小明

分析:

先用concat_ws函数将将星座和血型用“,”连接

在根据连接好的星座和血型group by

用collect_set函数对name聚合,

用concat_ws函数对聚合后的name用“|”分割

实现如下:

SELECTt1.c_b,CONCAT_WS("|",collect_set(t1.name))FROM (SELECTNAME,CONCAT_WS(',',constellation,blood_type) c_bFROM person_info)t1GROUP BY t1.c_b

列转行

数据、建表如下:

《疑犯追踪》 悬疑,动作,科幻,剧情

《Lie to me》 悬疑,警匪,动作,心理,剧情

《战狼 2》 战争,动作,灾难

create table movie_info(movie string,category string)row format delimited fields terminated by "\t";

需求如下:

将电影分类中的数组数据展开

《疑犯追踪》 悬疑

《疑犯追踪》 动作

《疑犯追踪》 科幻

《疑犯追踪》 剧情

《Lie to me》 悬疑

《Lie to me》 警匪

《Lie to me》 动作

《Lie to me》 心理

《Lie to me》 剧情

《战狼 2》 战争

《战狼 2》 动作

《战狼 2》 灾难

分析:

先用split函数将category根据“,”分割成数组

lateral view结合explode函数进行炸裂后的侧写

实现如下:

SELECTmovie,category_nameFROMmovie_infolateral VIEWexplode(split(category,",")) movie_info_tmp AS category_name;

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。