返回每个用户拥有的不同值的配置单元查询

utugiqy6  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(283)

我有一张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查询中,我就是写不出来。

1tuwyuhd

1tuwyuhd1#

不确定@invoketheshell的答案是否正确;它不能运行,需要6个乔布斯。这将使你在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和3…”
如我下面的评论所示,在给出的示例中,用户 D 从不访问值 3 . 我假设这是一个错别字,把它添加到数据集中,然后再添加一个 1 以及让更多 13 的。所以我的代码正确返回 3 ,这是所需的输出。如果您在实际的数据集上运行这个脚本,它也会产生正确的输出,因为没有“第二个distinct”。它唯一可能产生错误值的时候,是如果没有一个特定的数字被所有用户访问,这说明了我试图向@invoketheshell说明的一点:如果没有每个用户都访问过的单个数字,那么运行一个带有6个map reduce作业的查询是一个荒谬的方法来发现这一点。因为我们用的是 Hive 我相信,如果这个问题是一个“真实世界”的问题,那么它很可能会在至少100 TB的数据(可能更多)上执行。为了节省时间和资源,在运行一个大规模的查询之前,个人应该至少检查一个数字是否被所有用户访问过,而这个查询的分析取决于这个假设是否成立。

hsgswve4

hsgswve42#

这将返回列表中覆盖所有用户的第二个最常访问的值。表中没有一个值是我预期的数据输入错误。在实际数据中,您可能需要弄清楚如何处理多个关系。

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不是一个解决方案,因为不是每个用户都在数据中看到了该值。我希望您打算返回3个,但它并没有覆盖所有用户(用户d没有看到值3)。

相关问题