Ich habe immer über den UNION
Operator in SQL gewusst , aber erst kürzlich festgestellt, dass es andere Mengenoperatoren gibt, INTERSECT
und EXCEPT
. Ich konnte keinen Operator finden, der den vierten großen Mengenoperator ausführt, den symmetrischen Unterschied (z INTERSECT
. B. das Gegenteil von .)
Es sieht so aus, als könnte ich mit so etwas die gewünschte Ausgabe erzielen
SELECT Field FROM A UNION SELECT Field FROM B
EXCEPT
SELECT Field FROM A INTERSECT SELECT Field FROM B
(vorausgesetzt, ich habe den richtigen Vorrang) oder durch einen Anti-Full-Join:
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
Beide sehen jedoch nach ziemlich intensiven Abfragen aus, insbesondere im Vergleich zu den anderen drei grundlegenden Mengenoperationen. Gibt es eine symmetrische Differenzoperation in SQL und ich kann sie in der Dokumentation einfach nicht finden? Oder gibt es eine "kanonische" Möglichkeit, es in T-SQL zu implementieren?
quelle
(a EXCEPT b) UNION ALL (b EXCEPT a);
könnte effizienter sein.FULL JOIN
dies effizienter sein kann. Tests können zeigen, welches am besten ist. Und wenn mehr / unterschiedliche Spalten aus jeder Tabelle benötigt werden, ist meine Lösung natürlich nicht einfach zu erweitern.Antworten:
Alle Set-Operatoren werden in Joins oder Join-ähnliche Operatoren übersetzt. Sie können dies im Abfrageplan sehen.
Aus diesem Grund ist die vollständige äußere Verknüpfung, die Sie dort haben, die effizienteste, die Sie ausführen können. Wenn man natürlich die hoffentlich seltene Situation außer Acht lässt, in der der Optimierer einen schlechten Plan auswählt und ein Umschreiben durch Glück besser abschneidet. Das kann immer passieren.
quelle
SELECT Id FROM A WHERE <stuff> EXCEPT Select Id FROM A WHERE <other stuff>
und eine einzelne Liste von erhaltenId
. Ich kann nicht herausfinden, wie ich das mit einer vollständigen Verknüpfung machen soll ... muss ich mich nur darum kümmern, zwei Sätze vonId
Spalten zu haben und sie selbst wieder zusammenzufügen?ISNULL(a.Col, b.Col) AS Col
. Wickeln Sie das in eine abgeleitete Tabelle oder einen CTE ein, und Sie können die "gefaltete" Ergebnismenge für die weitere Bearbeitung verwenden. (Übrigens stimme ich zu, dass der symmetrische Differenzoperator existieren sollte.)Ich denke, das ist eine ziemlich gute Lösung. Es wird eine Vereinigung aller zwei Auswahlen mit Unterabfragen "Nicht vorhanden" verwendet. Besser als Union und Except zu kombinieren, da Sie Felder, die nicht übereinstimmen, in die Projektion aufnehmen können.
quelle