Eu sempre soube sobre o UNION
operador no SQL, mas só recentemente descobri que havia outros operadores de conjunto INTERSECT
e EXCEPT
. Não consegui encontrar um operador que faça o quarto operador de grande conjunto, a diferença simétrica (por exemplo, o oposto de INTERSECT
.)
Parece que posso obter a saída desejada usando algo como
SELECT Field FROM A UNION SELECT Field FROM B
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B
(supondo que eu tenha a precedência correta) ou executando uma junção anti-completa:
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
Mas os dois parecem consultas bastante intensivas, especialmente em comparação com as outras três operações básicas do conjunto. Existe uma operação de diferença simétrica no SQL e simplesmente não consigo encontrá-la na documentação? Ou existe uma maneira "canônica" de implementá-lo no T-SQL?
sql-server
t-sql
KutuluMike
fonte
fonte
(a EXCEPT b) UNION ALL (b EXCEPT a);
pode ser mais eficiente.FULL JOIN
pode ser mais eficiente. Os testes podem revelar qual é o melhor. E, claro, se forem necessárias mais / diferentes colunas de cada tabela, minha solução não será facilmente expansível.Respostas:
Todos os operadores definidos são traduzidos para junções ou operadores do tipo junção. Você pode testemunhar isso no plano de consulta.
Por esse motivo, a junção externa completa que você possui é a mais eficiente que você pode fazer. Desconsiderando, é claro, a esperançosamente rara situação na qual o otimizador escolhe um plano ruim e uma reescrita passa a ter um desempenho melhor por sorte. Isso sempre pode acontecer.
fonte
SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>
e obter uma única lista deId
. Não consigo descobrir como fazer isso com uma junção completa ... só preciso lidar com dois conjuntos deId
colunas e uni-las novamente?ISNULL(a.Col, b.Col) AS Col
. Embrulhe isso em uma tabela derivada ou CTE e você poderá usar o conjunto de resultados "dobrado" para mais operações nele. (Btw, eu concordo que o operador de diferença simétrica deva existir.)Eu acho que essa é uma solução muito boa. Ele usa uma união entre duas seleções com subconsultas Não existe. Melhor do que combinar Union e Except, porque você pode incluir campos que não coincidem na projeção.
fonte