J'ai toujours connu l' UNION
opérateur en SQL, mais je n'ai découvert que récemment qu'il y avait d'autres opérateurs d'ensemble, INTERSECT
et EXCEPT
. Je n'ai pas pu trouver d'opérateur qui fasse le quatrième grand opérateur d'ensemble, la différence symétrique (par exemple l'opposé de INTERSECT
.)
Il semble que je puisse obtenir la sortie souhaitée en utilisant quelque chose comme
SELECT Field FROM A UNION SELECT Field FROM B
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B
(en supposant que j'ai la priorité), ou en faisant une anti-jointure complète:
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
Mais les deux ressemblent à des requêtes assez intensives, en particulier par rapport aux trois autres opérations de base. Existe-t-il une opération de différence symétrique dans SQL et je ne la trouve tout simplement pas dans la documentation? Ou existe-t-il un moyen "canonique" de l'implémenter dans T-SQL?
la source
(a EXCEPT b) UNION ALL (b EXCEPT a);
pourrait être plus efficace.FULL JOIN
pourrait être plus efficace. Les tests peuvent révéler ce qui est le mieux. Et bien sûr, si des colonnes supplémentaires / différentes de chaque table sont nécessaires, ma solution n'est pas facilement extensible.Réponses:
Tous les opérateurs définis sont traduits en jointures ou opérateurs de type jointure. Vous pouvez en témoigner dans le plan de requête.
Pour cette raison, la jointure externe complète que vous avez est la plus efficace possible. Sans tenir compte, bien sûr, de la situation, espérons-le, rare dans laquelle l'optimiseur choisit un mauvais plan et une réécriture se produit mieux par chance. Cela peut toujours arriver.
la source
SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>
et obtenir une seule liste deId
. Je ne peux pas comprendre comment faire cela avec une jointure complète ... ai-je juste besoin de gérer deux ensembles deId
colonnes et de les réunir à nouveau moi-même?ISNULL(a.Col, b.Col) AS Col
. Enveloppez cela dans une table dérivée ou CTE et vous pouvez utiliser le jeu de résultats "plié" pour une opération ultérieure. (Btw, je suis d'accord que l'opérateur de différence symétrique devrait exister.)Je pense que c'est une assez bonne solution. Il utilise une union entre deux sélections avec des sous-requêtes Not Exists. Mieux que de combiner Union et Except car vous pouvez inclure des champs qui ne correspondent pas dans la projection.
la source