Hive通过查询获取组中的前n个记录

时间:2012-02-22 07:27:04

标签: user-defined-functions hive rank

我在hive中有以下表格

用户ID,用户名,用户地址,点击次数,展示次数,网页ID,网页名称

我需要通过每个页面的点击次数找到前5位用户[user-id,用户名,用户地址] [page-id,page-name]

据我所知,我们需要先按[page-id,page-name]进行分组,并在每个组中按照[点击次数,展示次数] desc排序,然后只排出前5位用户[user-id,user-name ,每个页面的用户地址,但我发现很难构建查询。

我们如何使用HIve UDF执行此操作?

5 个答案:

答案 0 :(得分:15)

修正了答案,修复了@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

请注意,rank()UDAF应用于page-id列,其新值用于重置或增加排名计数器(例如,为每个page-id分区重置计数器)

答案 1 :(得分:11)

从Hive 0.11开始,您可以使用Hive的内置rank()函数并使用Hive's built-in Analytics and Windowing functions使用更简单的语义来完成此操作。可悲的是,我找不到尽可能多的这些例子,但我们真的很有用。使用它们,内置了rank()和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 Jirathis guy's blog上找到更多(虽然不够我自己喜欢)的示例。

答案 2 :(得分:9)

您可以使用此处描述的rank()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

答案 3 :(得分:1)

我们说您的数据如下:

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

因此,对于page1,您将获得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

答案 4 :(得分:-1)

从(选择用户名,用户名,用户地址,页面,点击,row_num()到(。按点击顺序按页面顺序分区)a中选择* * a.row_num <= 5

在选择列时可能会有变化,但是逻辑是正确的。