Salah satu opsi adalah menggunakan FULL OUTER JOIN antara dua tabel dalam bentuk berikut:
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 ;
Sebagai contoh:
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 ;
Akan mengembalikan hitungan 2, sedangkan:
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 ;
mengembalikan harapan untuk hitungan 0.
Hal yang saya sukai dari metode ini adalah ia hanya perlu membaca setiap tabel satu kali vs membaca setiap tabel dua kali saat menggunakan EXISTS. Selain itu, ini harus berfungsi untuk basis data apa pun yang mendukung gabungan luar penuh (bukan hanya Postgresql).
Saya umumnya mengecilkan penggunaan klausa PENGGUNAAN tetapi di sini adalah satu situasi di mana saya percaya itu adalah pendekatan yang lebih baik.
Tambahan 2019-05-03:
Jika ada masalah dengan kemungkinan data nol, (yaitu kolom id tidak dapat dibatalkan tetapi nilai valnya), maka Anda dapat mencoba yang berikut ini:
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
, periksa pertanyaan ini: Cara efisien untuk membandingkan dua set data besar dalam SQL