一轴咱、排序函數(shù)
數(shù)據(jù)分析中实苞,排序的需求場景基礎(chǔ)且常見吉拳,如計算消費(fèi)金額TOP100的客戶等质帅,為此首先介紹基于效率優(yōu)化和場景應(yīng)用不同的三種排序函數(shù)。
Order by
order by語句用于對查詢結(jié)果集執(zhí)行全局排序,所有數(shù)據(jù)集中在一個reduce中進(jìn)行處理煤惩,默認(rèn)按照升序排序(ASC)嫉嘀,可以使用關(guān)鍵字DESC進(jìn)行降序排序;
在hive中使用order by的時候會受到mapred.mode屬性的約束魄揉,默認(rèn)為nonstrict模式剪侮;如果在strict模式下使用order by,必須使用limit關(guān)鍵字洛退,因為執(zhí)行order by的時候只能啟動單個reduce瓣俯,如果排序的結(jié)果集過大,那么執(zhí)行時間會非常漫長從而引起報錯兵怯。
語法:
select *
from order_tb
order by amt desc
-- limit 10
sort by
sort by在每個reduce中對數(shù)據(jù)進(jìn)行內(nèi)部排序彩匕,屬于局部排序∶角可以通過設(shè)置屬性mapred.reduce.tasks指定執(zhí)行的reduce個數(shù)驼仪,對輸出的數(shù)據(jù)再執(zhí)行歸并排序得到全部結(jié)果,如果設(shè)置的reduce個數(shù)為1的話袜漩,那么sort
by 語句和order by語句輸出結(jié)果一致绪爸。
語法:
select *
from order_tb
sort by amt
distribute by
distribute by會根據(jù)指定字段的值,將記錄分發(fā)到不同的reduce中宙攻,但是每個reduce中的數(shù)據(jù)并不是有序的奠货。默認(rèn)對指定列取hash值,然后hash值對reduce的個數(shù)取模座掘,模數(shù)相同的記錄進(jìn)入同一個reduce中递惋。通常,將distribute by和sort by連用雹顺,針對數(shù)據(jù)進(jìn)行指定劃分排序。
語法:
select *
from order_tb
distribute by year
sort by amt
二廊遍、窗口排序函數(shù)
互聯(lián)網(wǎng)面試中嬉愧,經(jīng)常會向面試者提出計算客戶連續(xù)登錄天數(shù)之類的問題,這時就需要靈活應(yīng)用窗口函數(shù)喉前,以下三種窗口排序函數(shù)也是必知基礎(chǔ)没酣。
Row_number()
rank()
Dense_rank()
語法:Row_number()/rank()/Dense_rank()? OVER ( PARTITION BY COL1? ORDER BY COL2 )
三個函數(shù)語法和功能一致,都需要和over()一起使用卵迂,函數(shù)將首先根據(jù)PARTITION BY后面的字段進(jìn)行分組裕便,在分組內(nèi)部根據(jù)ORDER BY后面的字段進(jìn)行排序,最終輸出每組內(nèi)部排序后的順序編號见咒,其中order by必須存在偿衰,PARTITION BY可以不設(shè)置。三者的不同體現(xiàn)在計算結(jié)果:
Row_number()?:為不重復(fù)連續(xù)排序,即1下翎、2缤言、3、4视事、…
rank():為可重復(fù)跳躍排序胆萧,即1、2俐东、2跌穗、4、…
Dense_rank() :為可重復(fù)連續(xù)排序虏辫,即1蚌吸、2、2乒裆、3套利、…
三、類型轉(zhuǎn)換函數(shù)
當(dāng)把時間作為分區(qū)字段鹤耍,通常會用字符串'20201202'記錄時間肉迫,再進(jìn)行日期運(yùn)算的時候就需要進(jìn)行類型轉(zhuǎn)換,介紹兩種將字符串轉(zhuǎn)換為日期的函數(shù):
cast(expr AS type)
將表達(dá)式expr轉(zhuǎn)換為指定type類型稿黄,是一種較為常見的類型轉(zhuǎn)換函數(shù)喊衫,如:cast('0123' as int) ;
需要注意的是杆怕,當(dāng)使用cast將字符串轉(zhuǎn)換為日期格式族购,字符串必須滿足yyyy-MM-dd格式,需嚴(yán)格使用如下格式才能實現(xiàn)日期轉(zhuǎn)換:Cast('2020-12-02'
as date) :輸出:2020-12-02
to_date(date_str, format)
將字符串格式的date_str轉(zhuǎn)換為指定的日期格式陵珍,也可以使用此日期專用函數(shù)實現(xiàn)類型轉(zhuǎn)換寝杖,即:to_date('20201202','yyyyMMdd'):輸出:2020-12-02
四、條件選擇函數(shù)
數(shù)據(jù)處理階段互纯,經(jīng)常需要對缺失值進(jìn)行處理瑟幕,尤其是表join時需注意空缺值的出現(xiàn)。以下2個函數(shù)簡潔方便:
ifnull(expr1, expr2)
如果表達(dá)式expr1為Null留潦,返回expr2只盹,否則返回expr1。特別適合用于空缺值的填充兔院,如:ifnull(amt , 0) 殖卑;
if(expr1, expr2, expr3)
如果表達(dá)式expr1成立,返回expr2坊萝,否則返回expr3孵稽。特別適合空缺值處理與邏輯判斷许起,如:if(id is not null, 1,0) ;
五、聚合計數(shù)函數(shù)
搭建完底層寬表肛冶,針對各種維度進(jìn)行匯總分析街氢,有時會用到聚合函數(shù):count(),返回一組值的計數(shù)值睦袖。通常有三種不同的統(tǒng)計方式:
count(*):統(tǒng)計所有行數(shù)珊肃,不會忽略為null的值;
count(1):用1代表代碼行進(jìn)行統(tǒng)計馅笙,等同于統(tǒng)計所有行數(shù)伦乔;
count(col):統(tǒng)計指定列的行數(shù),忽略值為null的行董习;
簡而言之烈和,count(*)與count(1)執(zhí)行結(jié)果相同,效率有所差異皿淋;count(col)與其結(jié)果不同招刹;