Eine Möglichkeit besteht darin, einen FULL OUTER JOIN zwischen den beiden Tabellen in der folgenden Form zu verwenden:
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 ;
Beispielsweise:
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 ;
Gibt eine Anzahl von 2 zurück, wobei:
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 ;
gibt die erhoffte Anzahl von 0 zurück.
Das, was ich an dieser Methode mag, ist, dass sie bei Verwendung von EXISTS jede Tabelle nur einmal und jede Tabelle nur zweimal lesen muss. Darüber hinaus sollte dies für jede Datenbank funktionieren, die vollständige äußere Verknüpfungen unterstützt (nicht nur Postgresql).
Ich rate generell von der Verwendung der USING-Klausel ab, aber hier ist eine Situation, in der ich glaube, dass dies der bessere Ansatz ist.
Nachtrag 2019-05-03:
Wenn es ein Problem mit möglichen Nulldaten gibt (dh die ID-Spalte ist nicht nullfähig, der Wert jedoch), können Sie Folgendes versuchen:
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