これはすでに Stack Overflowで尋ねられました ですが、MySQL専用です。 PostgreSQLを使用しています。残念ながら(そして意外にも)PostgreSQLには CHECKSUM table
。
PostgreSQLソリューションは問題ありませんが、一般的なソリューションの方が優れています。 http://www.besttechtools.com/articles/article/sql-query-to-check-two-tables-have-identical-data が見つかりましたが、使用されているロジックがわかりません。
背景:データベースを生成するコードを書き直したので、古いコードと新しいコードが同じ結果になるかどうかを確認する必要があります。
1つのオプションは、次の形式で2つのテーブル間でFULL OUTER JOINを使用することです。
SELECT count (1)
FROM table_a a
FULL OUTER JOIN table_b b
USING (<list of columns to compare>)
WHERE a.id IS NULL
OR b.id IS NULL ;
例えば:
CREATE TABLE a (id int, val text);
INSERT INTO a VALUES (1, 'foo'), (2, 'bar');
CREATE TABLE b (id int, val text);
INSERT INTO b VALUES (1, 'foo'), (3, 'bar');
SELECT count (1)
FROM a
FULL OUTER JOIN b
USING (id, val)
WHERE a.id IS NULL
OR b.id IS NULL ;
一方、2のカウントを返します。
CREATE TABLE a (id int, val text);
INSERT INTO a VALUES (1, 'foo'), (2, 'bar');
CREATE TABLE b (id int, val text);
INSERT INTO b VALUES (1, 'foo'), (2, 'bar');
SELECT count (1)
FROM a
FULL OUTER JOIN b
USING (id, val)
WHERE a.id IS NULL
OR b.id IS NULL ;
期待されるカウント0を返します。
この方法について私が気に入っているのは、EXISTSを使用する場合、各テーブルを1回だけ読み取るのに対して、各テーブルを2回読み取る必要があることです。さらに、これは(Postgresqlだけでなく)完全外部結合をサポートするすべてのデータベースで機能します。
私は一般的にUSING句の使用を推奨しませんが、これがより良いアプローチであると私が信じる状況の1つです。
追記2019-05-03:
Nullデータの可能性に問題がある場合(つまり、id列はnull可能ではありませんが、valは可能です)、次のことを試すことができます。
SELECT count (1)
FROM a
FULL OUTER JOIN b
ON ( a.id = b.id
AND a.val IS NOT DISTINCT FROM b.val )
WHERE a.id IS NULL
OR b.id IS NULL ;
EXCEPT
演算子を使用できます。たとえば、テーブルの構造が同じ場合、次の例では、1つのテーブルにあるが他のテーブルにはないすべての行を返します(テーブルに同じデータがある場合は0行です)。
_(TABLE a EXCEPT TABLE b)
UNION ALL
(TABLE b EXCEPT TABLE a) ;
_
または、EXISTS
を使用して、ブール値または2つの可能な結果の1つを含む文字列のみを返します。
_SELECT CASE WHEN EXISTS (TABLE a EXCEPT TABLE b)
OR EXISTS (TABLE b EXCEPT TABLE a)
THEN 'different'
ELSE 'same'
END AS result ;
_
SQLfiddle でテスト
また、EXCEPT
が重複を削除するわけではありません(テーブルに_PRIMARY KEY
_またはUNIQUE
制約がある場合は心配する必要はありませんが、重複する行を生成する可能性のある任意のクエリの結果を比較している場合もあります)。
EXCEPT
キーワードのもう1つのことは、NULL
の値を同じものとして扱うため、テーブルA
に_(1,2,NULL)
_の行があり、テーブルB
に_(1,2,NULL)
_の行がある場合、最初のクエリではこれらの行が表示されず、 2つのテーブルに他の行がない場合、2番目のクエリは_'same'
_を返します。
そのような行を異なるものとしてカウントしたい場合は、gsiemsの_FULL JOIN
_の回答のバリエーションを使用して、すべての(異なる)行を取得できます。
_SELECT *
FROM a NATURAL FULL JOIN b
WHERE a.some_not_null_column IS NULL
OR b.some_not_null_column IS NULL ;
_
はい/いいえの答えを得るには:
_SELECT CASE WHEN EXISTS
( SELECT *
FROM a NATURAL FULL JOIN b
WHERE a.some_not_null_column IS NULL
OR b.some_not_null_column IS NULL
)
THEN 'different'
ELSE 'same'
END AS result ;
_
2つのテーブルのすべての列がNULL可能ではない場合、2つのアプローチは同じ答えを与えます。
Except句が必要です
SELECT * FROM first_table
EXCEPT
SELECT * FROM second_table
これは、2番目のテーブルにない最初のテーブルのすべての行を返します
理解できないリンクされたコードを見る:
select count(*) from
(
select * From EmpDtl1
union
select * From EmpDtl2
)
秘密のソースはunion all
ではなくunion
を使用しています。前者は異なる行のみを保持しますが、後者は重複を保持します( 参照 )。言い換えると、ネストされたクエリは、「EmpDtl1からのすべての行と列、およびまだEmpDtl1にないEmpDtl2からの行と列を取得してください」と言います。 EmpDtl2が結果に行を提供しない場合、つまり2つのテーブルが同一である場合にのみ、このサブクエリの数はEmpDtl1の数と等しくなります。
または、キーシーケンスのテーブルを2つのテキストファイルにダンプし、選択した比較ツールを使用します。