Дьявол в деталях с этой, казалось бы, простой задачей.
Короткий и один из самых быстрых:
SELECT col1, col2
FROM (SELECT col1, col2, TRUE AS x1 FROM t1) t1
FULL JOIN (SELECT col1, col2, TRUE AS x2 FROM t2) t2 USING (col1, col2)
WHERE (x1 AND x2) IS NULL;
FULL [OUTER] JOIN
включает в себя все строки с обеих сторон, но заполняет значения NULL для столбцов пропущенных строк.WHERE
условия (x1 AND x2) IS NULL
идентифицируют эти несопоставленные строки.Эквивалент: WHERE x1 IS NULL OR x2 IS NULL
.
Чтобы исключить дубликаты пар, добавьте DISTINCT
(или GROUP BY
) в конце - дешевле на несколько dupes:
SELECT DISTINCT col1, col2
FROM ...
Если у вас есть много dupes с обеих сторон, дешевле сложить до объединения:
SELECT col1, col2
FROM (SELECT DISTINCT col1, col2, TRUE AS x1 FROM t1) t1
FULL JOIN (SELECT DISTINCT col1, col2, TRUE AS x2 FROM t2) t2 USING (col1, col2)
WHERE (x1 AND x2) IS NULL;
Сложнее, если может быть NULL-значений .DISTINCT
/ DISTINCT ON
или GROUP BY
рассматривают их как равные (поэтому дупс со значениями NULL складываются в подзапросах выше).Но условия JOIN
или WHERE
должны быть равны TRUE
для прохождения строк.Значения NULL не , считающиеся равными в этом, FULL [OUTER] JOIN
никогда не находят совпадения для пар, содержащих NULL.Это может или не может быть желательным.Вам просто нужно знать разницу и определить свои требования.
Рассмотрите добавленную демонстрацию в SQL Fiddle
Если нет значений NULL, нет дубликатов, но в каждой таблице определен дополнительный столбец NOT NULL
, например, первичный ключ, давайте назовем каждый id
, тогда он может быть таким простым, как :
SELECT col1, col2
FROM t1
FULL JOIN t2 USING (col1, col2)
WHERE t1.id IS NULL OR t2.id IS NULL;
Похожие: