日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hive udf 分组取top1_Hive中分组取前N个值的实现-row_number()

發布時間:2024/7/23 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hive udf 分组取top1_Hive中分组取前N个值的实现-row_number() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

背景

假設有一個學生各門課的成績的表單,應用hive取出每科成績前100名的學生成績。

這個就是典型在分組取Top N的需求。

解決思路

對于取出每科成績前100名的學生成績,針對學生成績表,根據學科,成績做order

by排序,然后對排序后的成績,執行自定義函數row_number(),必須帶一個或者多個列參數,如ROW_NUMBER(col1,

....),它的作用是按指定的列進行分組生成行序列。在ROW_NUMBER(a,b)

時,若兩條記錄的a,b列相同,則行序列+1,否則重新計數。

只要返回row_number()返回值小于100的的成績記錄,就可以返回每個單科成績前一百的學生

Sql代碼 ?

create?table?score_table?(

subject?string,

student?string,

score?int

)

partitioned?by?(date?string);

如果要查詢2012年每科成績前100的學生成績,sql如下

Java代碼 ?

create?temporary?function?row_number?as?'com.blue.hive.udf.RowNumber';

select?subject,score,student?from

(select?subject,score,student?from?score?where?dt='2012'?order?by?subject,socre?desc)?order_score

where?row_number(subject)?<=?100;

com.blue.hive.udf.RowNumber是自定義函數,函數的作用是按指定的列進行分組生成行序列。這里根據每個科目的所有成績,生成序列,序列值從1開始自增。

執行row_number函數,返回值如下

科目 成績 學生 row_number

物理 100 張一 1

物理 90 張二 2

物理 80 張三 3

.....

數學 100 李一 1

數學 90 李二 2

數學 80 李三 3

....

row_number的源碼

函數row_number(),必須帶一個或者多個列參數,如ROW_NUMBER(col1,

....),它的作用是按指定的列進行分組生成行序列。在ROW_NUMBER(a,b)

時,若兩條記錄的a,b列相同,則行序列+1,否則重新計數。

package com.blue.hive.udf;

import org.apache.hadoop.hive.ql.exec.UDF;

public class RowNumber extends UDF {

private static int MAX_VALUE = 50;

private static String comparedColumn[] = new String[MAX_VALUE];

private static int rowNum = 1;

public int evaluate(Object... args) {

String columnValue[] = new String[args.length];

for (int i = 0; i < args.length; i++) 『

columnValue[i] = args[i].toString();

}

if (rowNum == 1) {

for (int i = 0; i < columnValue.length; i++)

comparedColumn[i] = columnValue[i];

}

for (int i = 0; i < columnValue.length; i++) {

if (!comparedColumn[i].equals(columnValue[i])) {

for (int j = 0; j < columnValue.length; j++) {

comparedColumn[j] = columnValue[j];

}

rowNum = 1;

return rowNum++;

}

}

return rowNum++;

}

}

編譯后,打包成一個jar包,如/usr/local/hive/udf/blueudf.jar

然后在hive shell下使用,如下:

add jar /usr/local/hive/udf/blueudf.jar;

create temporary function row_number as 'com.blue.hive.udf.RowNumber';

select subject,score,student from

(select subject,score,student from score where dt='2012' order by subject,socre desc) order_score

where row_number(subject) <= 100;

同樣,這個函數可以用作去重操作。

可以替代大批量數據的DISTINCT

通過執行如:

select * from(

select type,value,row_number() as rn

from

log_table?distribute by type,value

sort by type,value

)

where rn = 1;

===============注意!============================

但是使用row_number()函數需要注意一點,必須使用sort

by。

測試的時候必須使用order by。

row_number()函數會假設數據有序的基礎上進行的。

總結

以上是生活随笔為你收集整理的hive udf 分组取top1_Hive中分组取前N个值的实现-row_number()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。