我有以下的蜂巢蜂巢獲得A組前N個記錄被查詢
用戶ID,用戶名,用戶地址,點擊次數,展示次數,頁面ID,頁面名稱
我表需要找出前5名用戶[用戶ID,用戶名,用戶地址]按點擊每一頁[第-ID,頁面名稱]
我明白,我們需要先將由[PAGE- id,page-name]以及我希望通過[點擊次數,展示次數] desc排序的每個組內,然後每個頁面僅發佈前5位用戶[用戶名,用戶名,用戶地址],但我發現很難構建查詢。
我們如何使用HIVE UDF來做到這一點?
我有以下的蜂巢蜂巢獲得A組前N個記錄被查詢
用戶ID,用戶名,用戶地址,點擊次數,展示次數,頁面ID,頁面名稱
我表需要找出前5名用戶[用戶ID,用戶名,用戶地址]按點擊每一頁[第-ID,頁面名稱]
我明白,我們需要先將由[PAGE- id,page-name]以及我希望通過[點擊次數,展示次數] desc排序的每個組內,然後每個頁面僅發佈前5位用戶[用戶名,用戶名,用戶地址],但我發現很難構建查詢。
我們如何使用HIVE UDF來做到這一點?
您可以用等級做()UDF描述這裏:http://ragrawal.wordpress.com/2011/11/18/extract-top-n-records-in-each-group-in-hadoophive/
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank(user-id) as rank, clicks
FROM mytable
DISTRIBUTE BY page-id, user-id
SORT BY page-id, user-id, clicks desc
) a
WHERE rank < 5
ORDER BY page-id, rank
修訂的答案,修復bug由@Himanshu Gahlot
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank(page-id) as rank, clicks FROM (
SELECT page-id, user-id, clicks FROM mytable
DISTRIBUTE BY page-id
SORT BY page-id, clicks desc
) a) b
WHERE rank < 5
ORDER BY page-id, rank
注意提到,秩() UDAF應用於page-id列,其新值用於重置或增加等級計數器(例如每個頁面分區的重置計數器)
酷..它保存了我的搜索:) – minhas23 2016-01-11 19:48:29
從Hive 0.11開始,您可以通過s使用Hive內置的rank()函數並使用更簡單的語義使用Hive's built-in Analytics and Windowing functions。可悲的是,我找不到像我喜歡的那樣多的例子,但它們確實非常有用。使用這些,均居()和WhereWithRankCond是建立在,所以你可以這樣做:需要
SELECT page-id, user-id, clicks
FROM (
SELECT page-id, user-id, rank()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM my table
) ranked_mytable
WHERE ranked_mytable.rank < 5
ORDER BY page-id, rank
沒有UDF,只有一個子查詢!此外,所有的排名邏輯都是本地化的。
您可以在這些功能in this Jira和this guy's blog上找到更多(儘管不夠我喜歡)的功能。
您可以使用each_top_k
function的hivemall
在Apache Hive上進行高效的top-k計算。
select page-id, user-id, clicks from ( select each_top_k(5, page-id, clicks, page-id, user-id) as (rank, clicks, page-id, user-id) from ( select page-id, user-id, clicks from mytable DISTRIBUTE BY page-id SORT BY page-id ) t1 ) t2 order by page-id ASC, clicks DESC
相比運行在蜂房的top-k查詢(例如,distributed by/rank
)的其他方法時,因爲它不保持中間結果整個排名的each_top_k
UDTF是非常快的。
讓我們假設你的數據看起來像以下:
page-id user-id clicks
page1 user1 10
page1 user2 10
page1 user3 9
page1 user4 8
page1 user5 7
page1 user6 7
page1 user7 6
page1 user8 5
page2 user1 20
page2 user2 19
page2 user3 18
下面的查詢會給你:
SELECT page-id, user-id, clicks, rank
FROM (
SELECT page-id, user-id, rank()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM your_table
) ranked_table
WHERE ranked_table.rank <= 5
結果:
page-id user-id clicks rank
page1 user1 10 1
page1 user2 10 1
page1 user3 9 3
page1 user4 8 4
page1 user5 7 5
page1 user6 7 5
page2 user1 20 1
page2 user2 19 2
page2 user3 18 3
因此,對於第1頁你得到6用戶,因爲點擊次數相同的用戶排名相同。
但是,如果您正在尋找5個用戶,並且隨機選擇多個用戶屬於同一個等級。您可以使用下面的查詢
SELECT page-id, user-id, clicks, rank
FROM (
SELECT page-id, user-id, row_number()
over (PARTITION BY page-id ORDER BY clicks DESC) as rank, clicks
FROM your_table
) ranked_table
WHERE ranked_table.rank <= 5
結果:
page-id user-id clicks rank
page1 user1 10 1
page1 user2 10 2
page1 user3 9 3
page1 user4 8 4
page1 user5 7 5
page2 user1 20 1
page2 user2 19 2
page2 user3 18 3
嗨馬克西姆,對不起打擾你這樣。我也有類似的問題。我已經發布了SO,但沒有得到任何好的反應,因爲我正在與Hive一起工作,而HiveQL對我來說是新的。 [http://stackoverflow.com/questions/11405446/find-10-latest-record-for-each-buyer-id-for-yesterdays-date](http://stackoverflow.com/questions/11405446/find- 10 - 最新記錄換每個買方-ID換昨日最新)。這對我很有幫助。 – ferhan 2012-07-10 22:18:11
我只是放了幾個小時做這項工作,但它沒有奏效。錯誤在於你先排名然後再做DISTRIBUTE BY和SORT BY。相反,您應該在外部查詢中應用排名,並在內部查詢中使用DISTRIBUTE BY和SORT BY。例如,SELECT page-id,user-id,點擊FROM(SELECT page-id,user-id,rank(user-id)as rank,點擊FROM(SELECT * FROM mytable DISTRIBUTE BY page-id,user-id SORT BY page-id,user-id,點擊DESC)a)b WHERE rank <5 ORDER BY page-id,rank; – 2013-03-19 21:30:53
確認@HimanshuGahlot是正確的。答案有* BUG *!您必須在外部查詢中使用rank(),並在內部查詢中使用DISTRIBUTE/SORT BY! – 2013-04-04 07:43:27