比较表并将差异结果写入文件/表

问题描述

我有两个具有相同架构/结构的表。两个表都可以包含另一个表中不存在的数据。
我需要找出它们之间的差异并将结果放入一个文件中。
ID 列是键,但可以有多个条目。

结果应该类似于差异表其中表 B 中表 A 中的行或表 A 中表 B 中的行的精确匹配应被忽略,所有其他应被捕获。。 >

我想到了使用 COALESCE 然后进行比较。
下面的示例表,当列数更多(10 列)时,是否有更好更快的方法来执行此操作?

Tables Below:

解决方法

通常可以使用 MINUS set operator + UNION ALL 解决:

(select * from t1 
minus
select * from t2)

UNION ALL 

(select * from t2
minus
select * from t1)

但问题是 Hive 不支持 MINUS 或 EXCEPT 运算符。

您可以使用左连接获取在一个表中不匹配的记录,并使用 UNION ALL 与另一个表中不匹配的记录。

select * from
(
select a.id,a.col1,a.col2,a.col3,'table_a' as src 
      from table_a 
           left join table_b 
                  on a.id=b.id 
                 and a.col1=b.col1 
                 and a.col2=b.col2 
                 and a.col3=b.col3
  where b.id is null --not matching in table_b

  UNION ALL --You may want to use UNION instead of UNION All to remove duplicates

select b.id,b.col1,b.col2,b.col3,'table_b' as src 
  from table_b 
       left join table_a 
              on a.id=b.id 
             and a.col1=b.col1 
             and a.col2=b.col2 
             and a.col3=b.col3
 where a.id is null --not matching in table_a
 ) s
 order by id,src; --order to put similar records together 

我添加了 src 列,因此您可以轻松识别该记录属于哪个表,如果不需要,您可以将其删除。

使用相关的 NOT EXISTS 而不是 LEFT JOIN 也可以做到同样的事情,但它在 Hive 中产生完全相同的计划,性能没有差异。

另外,如果您的表可以包含 NULL 并且您也想匹配它们, 在连接 NVL() 条件中使用 ON 函数,例如像这样:

NVL(a.col3,'NULL')=NVL(b.col3,'NULL') -- 对于数字列,使用一些常量,如 -999999 而不是 'NULL'