【问题标题】:Hive external table - Select unmatched recordHive 外部表 - 选择不匹配的记录
【发布时间】:2018-06-15 17:07:28
【问题描述】:

我创建了两个 Hive 外部表(可以使用 SQL 查询),它们指向我需要比较两个输出的位置。

我需要比较两个表并选择不匹配的记录。

表A

id   sdate   edate  tag

S1 20180610 20180611 0

S2 20180610 20180612 0

S3 20180612 20180613 0

S5 20180612 20180613 1

表B

id  sdate    edate  tag

S1 20180610 20180611 0

S2 20180611 20180612 0

S3 20180612 20180613 1

S4 20180612 20180613 1

需要的输出

S3 20180612 20180613 0

S5 20180612 20180613 1

S4 20180612 20180613 1

尝试通过连接两个表来编写查询,但对我不起作用。

感谢您对此的帮助

谢谢:)

【问题讨论】:

  • 您应该指定用于匹配的字段...不清楚为什么 S3 是结果的一部分,您是否使用了所有字段?
  • 很抱歉没有正确发布我的问题。我需要比较所有领域。那是我的挑战。 S3 应该选择,因为标签值与表 A 不同。
  • 请提供您尝试过的方法以及失败的方法。

标签: sql hive external-tables


【解决方案1】:

此查询将帮助您以有效的方式识别记录

create table unmatched as 
select 
a.*
from tableA as a left join (select *, true as flag from tableB) as b on
a.id=b.id a.sdate=b.sdate a.edate=b.edate a.tag=b.tag
where b.flag is null --this will get records in tableA but not in table B
union all 
select 
b.*
from tableB as b left join (select *, true as flag from tableA) as a on
a.id=b.id a.sdate=b.sdate a.edate=b.edate a.tag=b.tag
where a.flag is null --this will get records in tableB but not in table A
;

您可以使用完全连接来执行此操作,但效率会低得多

【讨论】:

  • FULL join 与 'A left join B UNION ALL B left join A' 相同。为什么你认为 FULL join 是低效的
  • 好问题!我想我应该添加更多的上下文。使用左连接将允许您根据数据的分布轻松创建一些优化。例如,如果您的键是倾斜分布的,您可以在子查询上运行(选择不同的键),您将无法在单个完全连接中执行此操作。
【解决方案2】:

我们可以使用以下查询轻松做到这一点。

请注意,我不确定您为什么要从输出中消除 s2,因为它在两个表中明显不同。

此外,如果您想在两个表中查找不同的记录,则 S3 将出现两次,因为两种情况下的标志值都不同。

您可以根据需要修改以下查询并获取结果。 由于我们只加入这些表一次,这比加入两次具有更好的性能。

select distinct
case when a.id is not null then a.id else b.id end as id,
case when a.sdate is not null then a.sdate else b.sdate end as sdate,
case when a.edate is not null then a.edate else b.edate end as edate,
case when a.tag is not null then a.tag else b.tag end as tag,
case when a.id is not null then 'table1' else 'table2'  end as tb_id
from table1 a
full join table2 b
on a.id=b.id 
and a.sdate=b.sdate 
and a.edate=b.edate 
and a.tag=b.tag
where (a.id is null
and a.sdate is null
and a.edate is null
and a.tag is null) 
or (b.id is null
and b.sdate is null
and b.edate is null
and b.tag is null)

【讨论】:

    【解决方案3】:
    select * from (select * from tableA
    union DISTINCT  
    select * from tableB) as finalTable
    where id not in (select * from tableA t1 join tableB t2
                  on t1.is=t2.id and t1.sdate=t2.sdate and t1.edate=t2.edate and t1.tag=t2.tag);
    

    第一个联合 DISTINCT 行并制作 finalTable 。它有所有唯一的行。

    然后在两个表之间进行内部连接。

    最后减去它们,现在你得到了答案。

    示例:

    如果你从第一个减去第二个,那么你得到 [1,4] 你想要哪个

    【讨论】:

    • 不需要完整的交叉产品,如果您无法执行地图连接,则在 mapreduce 中的成本非常高..
    • 我只使用sql而不是hive所以这样的sql查询
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    相关资源
    最近更新 更多