繁体   English   中英

比较 HIVE 中的两个表的相等性

[英]Comparing two tables for equality in HIVE

我有两个表,table1 和 table2。 每个都有相同的列:

key, c1, c2, c3

我想检查这些表是否彼此相等(它们具有相同的行)。 到目前为止,我有这两个查询(<> = 在 HIVE 中不相等):

select count(*) from table1 t1 
left outer join table2 t2
on t1.key=t2.key
where t2.key is null or t1.c1<>t2.c1 or t1.c2<>t2.c2 or t1.c3<>t2.c3

select count(*) from table1 t1
left outer join table2 t2
on t1.key=t2.key and t1.c1=t2.c1 and t1.c2=t2.c2 and t1.c3=t2.c3
where t2.key is null

所以我的想法是,如果返回零计数,则表是相同的。 但是,第一个查询的计数为零,第二个查询的计数为非零。 它们究竟有何不同? 如果有更好的方法来检查这个肯定让我知道。

第一个排除 t1.c1、t1.c2、t1.c3、t2.c1、t2.c2 或 t2.c3 为空的行。 这意味着您有效地进行了内部联接。

第二个将查找存在于 t1 但不在 t2 中的行。

要同时查找 t2 中存在但 t1 中不存在的行,您可以执行完整的外部联接。 以下 SQL 假设所有列都不是NOT NULL

select count(*) from table1 t1
full outer join table2 t2
on t1.key=t2.key and t1.c1=t2.c1 and t1.c2=t2.c2 and t1.c3=t2.c3
where t1.key is null /* this condition matches rows that only exist in t2 */
   or t2.key is null /* this condition matches rows that only exist in t1 */

如果要检查重复项并且表具有完全相同的结构并且表中没有重复项,则可以执行以下操作:

select t.key, t.c1, t.c2, t.c3, count(*) as cnt
from ((select t1.*, 1 as which from table1 t1) union all
      (select t2.*, 2 as which from table2 t2)
     ) t
group by t.key, t.c1, t.c2, t.c3
having cnt <> 2;

如有必要,您可以通过多种方式放松第一段中的条件。

请注意,当列具有NULL值时,此版本也适用。 这些可能会导致您的数据出现问题。

嗯,最好的方法是计算每个表的哈希和,并比较哈希的和。 所以不管有多少列,不管是什么数据类型,只要两个表的schema相同,就可以使用如下查询进行比较:

select sum(hash(*)) from t1;
select sum(hash(*)) from t2;

你只需要比较返回值。

我建议您不要使用任何 JOIN 来尝试比较表:

  • 当表很大时,这是一项非常昂贵的操作(在 Hive 中通常是这种情况)
  • 当某些行/“连接键”重复时,它可能会出现问题

(当数据位于不同的集群/数据中心/云中时,它也可能不切实际)。

相反,我认为最好使用校验和方法并比较两个表的校验和。

我开发了一个 Python 脚本,可以让您轻松进行此类比较,并查看网络浏览器中的差异:

https://github.com/bolcom/hive_compared_bq

我希望能帮到你!

另一个变种

select c1-c2 "different row counts"
, c1-c3 "mismatched rows" 
from 
( select count(*) c1 from table1)
,( select count(*) c2 from table2 )
,(select count(*) c3 from table1 t1, table2 t2
    where t1.key= t2.key
    and T1.c1=T2.c1 )

尝试使用 WITH 子句:

With cnt as(
   select count(*) cn1 from table1
   )
   select 'X' from dual,cnt where cnt.cn1 = (select count(*) from table2); 

一种简单的解决方案是进行内连接。 假设我们有两个 hive 表,即 table1 和 table2。 两个表都有相同的列,即 col1、col2 和 col3。 行数也应该相同。 然后命令如下

**

select count(*) from table1 
inner join table2 
on  table1.col1 = table2.col1 
and table1.col2 = table2.col2
and table1.col3 = table2.col3 ;

**

如果输出值与 table1 和 table2 中的行数相同,则所有列都具有相同的值,但是如果输出计数小于某些数据不同。

首先计算表 C1 和 C2 的计数。 C1 和 C2 应该相等。 C1 和 C2 可以从以下查询中获得

select count(*) from table1

如果 C1 和 C2 不相等,则表不相同。

2:为表 DC1 和 DC2 找到不同的计数。 DC1 和 DC2 应该相等。 可以使用以下查询找到不同记录的数量:

select count(*) from (select distinct * from table1)

如果 DC1 和 DC2 不相等,则表不相同。

3:现在获取通过对 2 个表执行联合获得的记录数。 设为 U。 使用以下查询获取 2 个表的联合中的记录数:

SELECT count (*)
 FROM 
    (SELECT *
    FROM table1
    UNION
    SELECT *
    FROM table2)

如果2个表的distinct count等于2个表合并得到的记录数,可以说2个表中的数据是相同的。 即 DC1 = U 和 DC2 = U

我使用了 EXCEPT 语句并且它起作用了。

select * from Original_table
EXCEPT
select * from Revised_table

将向我们显示原始表中不在修订表中的所有行。

如果您的表已分区,则必须提供分区谓词。 仅供参考,如果您使用 Presto 并通过 SQL 实验室查询,则不需要提供分区值。

使用MINUS运算符:

SELECT count(*) FROM
  (SELECT t1.c1, t1.c2, t1.c3 from table1 t1
    MINUS
  SELECT t2.c1, t2.c2, t2.c3 from table2 t2)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM