web-dev-qa-db-ja.com

HIVEでの2つのテーブルの同等性の比較

Table1とtable2の2つのテーブルがあります。同じ列のそれぞれ:

key, c1, c2, c3

これらのテーブルが互いに等しいかどうかを確認したい(同じ行がある)。これまでのところ、次の2つのクエリがあります(<> = 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

だから私の考えは、ゼロのカウントが返された場合、テーブルは同じであるということです。ただし、最初のクエリのカウントがゼロになり、2番目のクエリのカウントがゼロ以外になります。それらはどのように正確に異なりますか?これを確認するより良い方法がある場合は、必ずお知らせください。

11
Danzo

最初のものは、t1.c1、t1.c2、t1.c3、t2.c1、t2.c2、またはt2.c3がnullである行を除外します。つまり、内部結合を効果的に行うことができます。

2つ目は、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 */
12
Klas Lindbäck

重複をチェックしたい場合andテーブルの構造はまったく同じですandテーブルの重複がないため、次のことができます。

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値がある場合にも機能することに注意してください。これらはデータに問題を引き起こしている可能性があります。

6
Gordon Linoff

テーブルを比較するためにJOINを使用しないことをお勧めします。

  • テーブルが大きい場合は、非常にコストのかかる操作です(Hiveの場合がよくあります)。
  • 一部の行/「結合キー」が繰り返されると問題が発生する可能性があります

(また、データが異なるクラスター/データセンター/クラウドにある場合は、実用的でない場合もあります)。

代わりに、チェックサムアプローチを使用して両方のテーブルのチェックサムを比較するのが最善だと思います。

私はPythonスクリプトを開発しました。このスクリプトを使用すると、このような比較を簡単に行うことができ、Webブラウザーで違いを確認できます。

https://github.com/bolcom/Hive_compared_bq

お役に立てれば幸いです。

1
Sourygna

WITH句で試してください:

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

簡単な解決策の1つは、内部結合を行うことです。 2つの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の行数と同じ場合、すべての列は同じ値になります。ただし、出力数が少ない場合、一部のデータが異なります。

0
Sandeep Kumar

最初に、テーブル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つのテーブルの個別のカウントが2つのテーブルの結合を実行して取得したレコードの数と等しい場合、2つのテーブルのデータは同じであると言えます。つまり、DC1 = UおよびDC2 = U

0
pkhabya

別の変形

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 )
0
Randy