Hive Query返回每个User拥有的不同值

时间:2015-07-02 20:05:43

标签: mysql hadoop hive hiveql

我有一个mysql表 -

User    Value
A   1
A   12
A   3
B   4
B   3
B   1
C   1
C   1
C   8
D   34
D   1
E   1
F   1
G   56
G   1
H   1
H   3
C   3
F   3
E   3
G   3

我需要运行一个查询,它返回每个用户拥有的第二个不同的值。 表示每个用户访问任何2个值,然后根据事件选择第二个不同的值。

  

如上所述1&每个用户正在访问3。发生1是   超过3,所以第二个不同将是3

所以我想我会先得到所有不同的用户。

create table temp AS Select distinct user from table;

然后我会有一个外部查询 -

Select value from table where value in (...)

以编程方式,我可以遍历每个用户包含的值,例如Map,但在Hive查询中,我只是无法写出来。

2 个答案:

答案 0 :(得分:0)

这将返回列表中跨越所有用户的第二个最常用的值。表中没有这些值,我预计数据中会出现拼写错误。在实际数据中,您可能需要了解如何处理的多重关系。

Select value as second_distinct from
 (select value, rank() over (order by occurrences desc) as rank
 from
   (SELECT value, unique_users, max(count_users) as count_users, count(value) as occurrences
     from
        (select value, size(collect_set(user) over (partition by value)) 
         as count_users from my_table
        ) t
     left outer join
        (select count(distinct user) as unique_users from my_table
        ) t2 on (1=1)
        where unique_users=count_users
        group by value, unique_users
    ) t3
 ) t4
where rank = 2;

这很有效。它返回NULL,因为只有访问每个用户的值(值为1)。值3不是解决方案,因为并非每个用户都在您的数据中看到过该值。我希望你打算返回三个但是它不会跨越所有用户(用户D没有看到值3)。

答案 1 :(得分:0)

不确定@ invoketheshell的答案是如何标记正确的;它没有运行,它需要6个MR作业。这将使您在4中获得更少的代码。

<强>查询

select value
from (
  select value, value_count, rank() over (order by value_count desc) rank
  from (
    select value, count(value) value_count
    from (
      select value, num_users, max(num_users) over () max_users
      from (
        select value
          , size(collect_set(user) over (partition by value)) num_users
        from db.table ) x ) y
    where num_users = max_users
    group by value ) z ) f
where rank = 2

<强>输出

3

编辑:让我澄清我的解决方案,因为似乎有些混乱。 OP的例子说

  

“因此,每个用户正在访问1&amp; 3以上......”

正如我在下面的评论所示,在给出的示例中,用户D永远不会访问值3。我假设这是一个拼写错误并将其添加到数据集中,然后添加另一个1以使13更多。{所以我的代码正确返回3,这是所需的输出。如果您在实际数据集上运行此脚本,它也将生成正确的输出,这是没有的,因为没有“2nd Distinct”。 可能产生错误值的唯一时间是,如果所有用户都访问过没有一个特定的数字,这说明我试图对@ invoketheshell:如果每个用户都没有访问过单个号码,那么 运行带有6个map-reduce作业的查询是一种荒谬的方式来查找它。 因为我们正在使用Hive我认为,如果这个问题是一个“现实世界”的问题,它很可能会在至少100个TB数据(可能更多)上执行。我有兴趣保留时间和资源,在运行大量查询之前,至少要检查所有用户是否已访问过一个号码,其分析取决于该假设是否正确。