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を使用する場合に各テーブルを2回読み取るのに対して、各テーブルを1回読み取るだけで済むことです。さらに、これは(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
:この質問をチェック、SQLで二つの大きなデータセットを比較するための効率的な方法