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番目のクエリのカウントがゼロ以外になります。それらはどのように正確に異なりますか?これを確認するより良い方法がある場合は、必ずお知らせください。
最初のものは、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 */
重複をチェックしたい場合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
値がある場合にも機能することに注意してください。これらはデータに問題を引き起こしている可能性があります。
テーブルを比較するためにJOINを使用しないことをお勧めします。
(また、データが異なるクラスター/データセンター/クラウドにある場合は、実用的でない場合もあります)。
代わりに、チェックサムアプローチを使用して両方のテーブルのチェックサムを比較するのが最善だと思います。
私はPythonスクリプトを開発しました。このスクリプトを使用すると、このような比較を簡単に行うことができ、Webブラウザーで違いを確認できます。
https://github.com/bolcom/Hive_compared_bq
お役に立てれば幸いです。
WITH句で試してください:
With cnt as(
select count(*) cn1 from table1
)
select 'X' from dual,cnt where cnt.cn1 = (select count(*) from table2);
簡単な解決策の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の行数と同じ場合、すべての列は同じ値になります。ただし、出力数が少ない場合、一部のデータが異なります。
最初に、テーブル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
別の変形
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 )