應用場景:假設有一個分類圖書銷量表,要求應用HIVE函數取出每類銷量排名前3的圖書及銷量。
解決思路:這屬於典型的分組取TopN的需求。根據需求,可以針對圖書銷量表,根據圖書類目、銷量進行order by排序,然後對排序後的銷量執行自定義函數row_number(),
JDH代碼:
SELECT
category,
sku_id,
sales
FROM
(
SELECT * FROM book_sales order by category, sales desc
)
where
row_number(category) <= 3
結果示例:
假設銷售表的記錄如下
類目
商品編號
銷量
管理類
1001
300
經濟類
2001
340
投資類
3001
200
管理類
1002
240
經濟類
2002
180
投資類
3002
160
管理類
1003
100
經濟類
2003
100
投資類
3003
320
管理類
1004
500
經濟類
2004
10
投資類
3004
80
……
經過order by全局排序後,記錄如下
類目
商品編號
銷量
管理類
1004
500
管理類
1001
300
管理類
1002
240
管理類
1003
100
……
經濟類
2001
340
經濟類
2002
180
經濟類
2003
100
經濟類
2004
10
……
投資類
3003
320
投資類
3001
200
投資類
3002
160
投資類
3004
80
……
接著執行row_number函數,返回值如下
類目
商品編號
銷量
row_number
管理類
1004
500
1
管理類
1001
300
2
管理類
1002
240
3
管理類
1003
100
4
……
經濟類
2001
340
1
經濟類
2002
180
2
經濟類
2003
100
3
經濟類
2004
10
4
……
投資類
3003
320
1
投資類
3001
200
2
投資類
3002
160
3
投資類
3004
80
4
……
注意:必須保證row_number執行是在reducer中執行,因為hive是基於MAPREADUCE的,上述的語句保證了銷售表的記錄按照類目和銷量做了全局排序,然後在reducer端執行row_number函數,如果在map端執行了row_number,那麼結果將是錯誤的。