Я всегда знал об UNION
операторе в SQL, но только недавно обнаружил, что были и другие операторы множеств, INTERSECT
и EXCEPT
. Я не смог найти оператора, который выполняет четвертый оператор большого набора, симметричную разность (например, противоположность INTERSECT
.)
Похоже, я могу получить желаемый результат, используя что-то вроде
SELECT Field FROM A UNION SELECT Field FROM B
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B
(при условии, что я правильно понял приоритет) или с помощью анти-полного объединения:
SELECT A.Field, B.Field
FROM A
FULL JOIN B ON B.Id = A.Id
WHERE B.Id IS NULL OR A.Id IS NULL
Но оба они выглядят как довольно интенсивные запросы, особенно по сравнению с тремя другими основными операциями над множествами. Есть ли в SQL симметричная разностная операция, и я просто не могу найти ее в документации? Или есть «канонический» способ реализовать его в T-SQL?
sql-server
t-sql
KutuluMike
источник
источник
(a EXCEPT b) UNION ALL (b EXCEPT a);
может быть более эффективным.FULL JOIN
может быть более эффективным. Тестирование может выявить, что лучше. И, конечно же, если требуется больше / разных столбцов в каждой таблице, моё решение нелегко расширить.Ответы:
Все операторы множеств переводятся в соединения или операторы, подобные соединениям. Вы можете убедиться в этом в плане запроса.
По этой причине полное внешнее соединение, которое у вас есть, является наиболее эффективным, что вы можете сделать. Конечно, несмотря на редкую ситуацию, в которой оптимизатор выбирает неверный план, а перезапись оказывается более удачной благодаря удаче. Это всегда может случиться.
источник
SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>
и получить один списокId
. Я не могу понять, как сделать это с полным объединением ... мне просто нужно иметь дело с двумя наборамиId
столбцов и объединять их вместе самостоятельно?ISNULL(a.Col, b.Col) AS Col
. Оберните это в производную таблицу или CTE, и вы сможете использовать «свернутый» набор результатов для дальнейшей работы с ним. (Кстати, я согласен, что симметричный разностный оператор должен существовать.)Я думаю, что это довольно хорошее решение. Он использует объединение всех двух выборок с подзапросами Not Exists. Лучше, чем объединение Union и Except, потому что вы можете включить поля, которые не совпадают в проекции.
источник