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