好了览闰,接下來咱們來看看如何在Hive中實現(xiàn)一行轉(zhuǎn)多行的操作,主要介紹explode和posexplode函數(shù)的使用问拘。
沿用上一節(jié)的數(shù)據(jù)遍略,從簡單到復(fù)雜,咱們一步步來骤坐。
1绪杏、數(shù)據(jù)介紹
先看下我們的數(shù)據(jù),主要包括三列纽绍,分別是班級蕾久、姓名以及成績,數(shù)據(jù)表名是default.classinfo拌夏。
2僧著、單列Explode
首先來看下最基本的,我們?nèi)绾伟裺tudent這一列中的數(shù)據(jù)由一行變成多行障簿。這里需要使用split和explode盹愚,并結(jié)合lateral view實現(xiàn)。代碼如下:
select
class,student_name
from
default.classinfo
lateral view explode(split(student,',')) t as student_name
結(jié)果如下:
3站故、單列Posexplode
接下來皆怕,我們想要給每個同學(xué)來一個編號,假設(shè)編號就按姓名的順序世蔗,此時我們要用到另一個hive函數(shù)端逼,叫做posexplode,代碼如下:
select
class,student_index + 1 as student_index,student_name
from
default.classinfo
lateral view posexplode(split(student,',')) t as student_index,student_name
這里select時對編號+1主要是因為編號是從0開始的污淋,結(jié)果如下:
4顶滩、多列Explode
好了,我們繼續(xù)前進寸爆。這次我們想基于兩列explode礁鲁,同時能夠使學(xué)生和其成績能夠匹配,即期望的效果如下:
顯然我們要對兩列進行explode赁豆,先試試行不行:
select
class,student_name,student_score
from
default.classinfo
lateral view explode(split(student,',')) sn as student_name
lateral view explode(split(score,',')) sc as student_score
結(jié)果如下:
好像是不太行仅醇,如果我們分別對兩列進行explode的話,假設(shè)每列都有三個值魔种,那么最終會變成3 * 3 = 9行析二。但我們想要的結(jié)果只有三行。此時我們可以進行兩次posexplode,姓名和成績都保留對應(yīng)的序號叶摄,即使變成了9行属韧,我們通過where條件只保留序號相同的行即可。代碼如下:
select
class,student_name,student_score
from
default.classinfo
lateral view posexplode(split(student,',')) sn as student_index_sn,student_name
lateral view posexplode(split(score,',')) sc as student_index_sc,student_score
where
student_index_sn = student_index_sc
此時結(jié)果就對了:
好了蛤吓,到這里本應(yīng)該就結(jié)束了宵喂,假設(shè)我們又想對同學(xué)的成績進行一下排名該怎么做呢?當然是借助rank函數(shù)啦(row_number函數(shù)對于相同的成績也會賦予不同的排名会傲,所以我們選擇rank函數(shù)锅棕,關(guān)于二者的區(qū)別我們后續(xù)再細講):
select
class,
student_name,
student_score,
rank() over(partition by class order by student_score desc) as student_rank
from
default.classinfo
lateral view posexplode(split(student,',')) sn as student_index_sn,student_name
lateral view posexplode(split(score,',')) sc as student_index_sc,student_score
where
student_index_sn = student_index_sc
order by class,student_rank
結(jié)果符合我們預(yù)期:
好了,本文就到這里了淌山!下期再見裸燎!