Hive - 如何通过列A和B以及不同的列C组合组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive - 如何通过列A和B以及不同的列C组合组相关的知识,希望对你有一定的参考价值。

我需要创建一个查询,从特定的表中选择具有多个不同电子邮件的用户。为了区分用户,我根据两个字段对它们进行分组:名称和年龄。让我们看一个例子。

所以我有一个这样的表:

name     age    email       phone
----------------------------------
Andy     20     Andy@du     1234
Berni    21     Berni@du    2345
Carol    22     Carol@du    3456
Andy     20     Andy@du     4321
Berni    21     Berni@et    2345
Dody     28     Dodi@du     7869
Carol    22     Carol@pt    3456

我想得到的是:

Berni    21    Berni@du, Berni@et
Carol    22    Carol@du, Carol@pt

请注意,Andy在数据库中也是两次,但使用相同的电子邮件(电话号码有什么变化)。由于此用户,我需要对电子邮件进行区分,因此仅选择具有两个不同电子邮件的用户。

通过此查询,我能够解决问题并获得所需的结果。

select * from 
(
    select  aux.name, 
            aux.age, 
            concat_ws(',',collect_set(email)) as email
    FROM
    (select a.name, a.age, a.email
        FROM TestUsers a
        RIGHT JOIN 
        (select  name,
                 age
                FROM TestUsers
                GROUP BY 
                name,
                age
                having count(*) > 1
        )b
    ON  a.name = b.name 
    AND a.age = b.age
    )aux
    GROUP BY aux.name, 
             aux.age
)tr
where locate(",",tr.email) > 0;

但我确信它必须比检查电子邮件字段中何时没有逗号(这意味着多个电子邮件)更有效。

有没有人想到更好的方法?

答案

如果我理解正确,你应该能够使用having条款来做到这一点:

select tu.name, tu.age,
       concat_ws(',', collect_list(tu.email)) as emails
from (select distinct tu.name, tu.age, tu.email
      from TestUsers tu
     ) tu
group by tu.name, tu.age
having count(*) > 1;

实际上,因为collect_set()删除了重复项,所以这应该没有子查询:

select tu.name, tu.age,
       concat_ws(',', collect_set(tu.email)) as emails
from testusers tu
group by tu.name, tu.age
having min(tu.email) <> max(tu.email);

以上是关于Hive - 如何通过列A和B以及不同的列C组合组的主要内容,如果未能解决你的问题,请参考以下文章

组合两个不同数据集的列

如何在 HIVE 中合并具有不同模式的表?

为每个列单元格展开列单元格

我想在表 A 中提取一些在表 B 中没有条目的列。如何在 Hive 中实现这一点?

Datatable LINQ select datarow 只返回一行以及如何排序

如何分别为不同的列创建热图?