一种选择是以以下形式在两个表之间使用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时两次读取每个表相比,它只需要读取一次表。此外,这对支持完全外部联接的数据库(不只是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来比较两个大型数据集