Один із варіантів полягає у використанні ПОВНОГО ВИХІДНОГО ПРИЄДНАННЯ між двома таблицями у такій формі:
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. Крім того, це повинно працювати для будь-якої бази даних, яка підтримує повне зовнішнє з'єднання (не лише Postgresql).
Я, як правило, не рекомендую використовувати пункт USING, але ось одна ситуація, коли я вважаю, що це буде кращим підходом.
Додаток 2019-05-03:
Якщо виникає проблема з можливими нульовими даними (тобто стовпець id не є нульовим, але 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