hive中分組計算top N
平時在做數據查詢時,有一種需求就是,對數據分組後,我只想看每組數據的前幾個值。這個用hive怎麼處理呢,總不能每組數據都單獨計算,再排序取limit吧。
幸好hive還有UDF。這可是個大招。
下面介紹下具體招式:
1. 編寫一個UDF程序。
public classRankextendsUDF {
private intcounter;
privateStringlast_key;
public intevaluate(finalString key) {
if( !key.equalsIgnoreCase(this.last_key)) {
this.counter=;
this.last_key= key;
}
return this.counter++;
}
}
看到此處迷糊不看我加點注釋:當udf的evaluate方法接收到hive傳進來的一個欄位的值時,
會用這個值跟上一個值對比,如果一致那麼將計數器counter加一,不一致,就將counter置為0。
簡單吧。
2. hql語句中的應用
舉個,我們要先對數據按照某個key分組,然後對每一組的數據按某個value排降序後取前5個。
select K,F,c_v
FROM
(SELECT *, rank(K) as row_number
FROM
(select K,F,c_V from
(select K,F,count(distinct V) as c_V from T1 group by K,F)a
DISTRIBUTE BY K,F sort by K,F,c_V desc)b
)c
WHERE row_number
是不是又迷糊了?,這樣的啊,首先我們對數據按照欄位K,F 分組統計V的個數。group分組後按照K,F和V的個數排降序。在保證數據按照K,F有序後,將K傳入之前的UDF中,在UDF中會對每個K,返回一個row_number。這個row_number表示,相同的K中的數據行號。這樣就得到了相同K對應的數據的行號。然後取行號小於6也就是前五個(因為之前已經拍過降序了,所以此處會取的前五個)。這樣就得到了相同K的對應的V的top 5了。
3. 當然最重要的是,在執行hive語句前,我們要引入這個udf。
1. 對之前的udf代碼打包。
2.將jar包上傳,並引用。
// 引用jar包
add jar /xxx/hive-udf/hive_udf-1.0-SNAPSHOT-jar-with-dependencies.jar;
// 建立一個方法指定到這個udf類
4. 最後你可能會問,DISTRIBUTE是幹嘛的?
稍等,我百度下啊
。。。。。。。。。。。。。
。。。。。。。。。。。。。
。。。。。。。。。。。。。
。。。。。。。。。。。。。
查到了,據百度說,這個是把相同的key放到一個reduce中,再結合sort by,可以實現全局排序。明白了吧。


※查詢退款進度&如何提交申請
※安貧詩歌/它們無恥,它們就是美的
※袁雨欣《一起談電視》
※核保小知識—身高與體重的核保判讀
※今天,他們的婚禮不再推延
TAG:公眾號 |