In SQL is de UNION
clausule voegt de resultaten van twee zoekopdrachten samen tot een enkele resultaatset.
U kunt de UNION
. gebruiken clausule met of zonder de ALL
argument:
UNION ALL
– Bevat duplicaten.UNION
– Sluit duplicaten uit.
Hieronder staan enkele basisvoorbeelden om te laten zien hoe het werkt.
Voorbeeldtabellen
Stel dat we twee tabellen hebben:Cats
en Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
We kunnen een SELECT
. gebruiken statement met een UNION
clausule om de resultaten van beide tabellen te combineren in één resultaatset.
Voorbeeld met UNION ALL
Laten we eerst UNION ALL
. gebruiken zodat het duplicaten bevat.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Resultaat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
In dit geval worden zeven rijen geretourneerd. We kunnen zien dat "Fetch" twee keer wordt geretourneerd. Dit komt omdat er twee honden zijn die Fetch heten.
Er zijn ook een kat en een hond met dezelfde naam:Fluffy.
Merk op dat ik een kolomalias heb gebruikt om het veld dat door de bewerking wordt geretourneerd een naam te geven. Als ik dat niet had gedaan, zou het resultaat de kolomnamen van de eerste zoekopdracht hebben gebruikt. In dat geval zou de kolomkop DogName
. hebben heten in plaats van PetName
.
SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Resultaat:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
Dit kan al dan niet acceptabel zijn, afhankelijk van de gegevens die u in uw zoekopdracht retourneert. In ons geval is het niet gepast, omdat niet alle resultaten honden zijn.
Voorbeeld met UNION
Laten we eens kijken wat er gebeurt als we de ALL
. verwijderen argument.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Resultaat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Deze keer worden er slechts vijf rijen geretourneerd. Beide duplicaten zijn verwijderd.
UNION
vs DISTINCT
Merk op dat dit anders is dan het toepassen van DISTINCT
aan elke individuele SELECT
uitspraak. Als we dat hadden gedaan, zou Fluffy twee keer zijn geretourneerd, omdat de ALL
zou alleen gelden voor de SELECT
verklaring dat het wordt toegepast tegen (niet op de aaneengeschakelde resultaten).
Hier is een voorbeeld om te illustreren wat ik bedoel.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Resultaat:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
Alle zoekopdrachten moeten hetzelfde aantal kolommen retourneren
Wanneer u de UNION
. gebruikt clausule, moet elke zoekopdracht hetzelfde aantal kolommen hebben en ze moeten in dezelfde volgorde staan.
Zo niet, dan krijg je een foutmelding.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;
Resultaat:
Msg 205, Level 16, State 1, Line 1 All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
Dat is de fout die SQL Server retourneert bij gebruik van een ongelijk aantal kolommen. Deze specifieke fout geeft aan dat dezelfde beperking ook van toepassing is op de INTERSECT
en EXCEPT
exploitanten. Het foutbericht dat u ontvangt kan verschillen, afhankelijk van uw DBMS.
Gegevenstypen moeten compatibel zijn
Naast het vereiste van hetzelfde aantal kolommen, moeten die kolommen ook een compatibel gegevenstype hebben.
Ze hoeven niet noodzakelijk van hetzelfde gegevenstype te zijn, maar ze moeten wel compatibel zijn. Dat wil zeggen, ze moeten compatibel zijn door middel van impliciete conversie. Als de gegevenstypen niet overeenkomen, moet het DBMS een impliciete conversie kunnen uitvoeren zodat ze wel overeenkomen.
Zo niet, dan krijg je een foutmelding.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;
Resultaat:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Meow' to data type int.
De resultaten bestellen
Als u de resultaten wilt sorteren met de ORDER BY
clausule, moet u deze op de laatste vraag plaatsen. Je kunt geen aparte ORDER BY
. plaatsen clausule op elke zoekopdracht, of wat dat betreft, elke zoekopdracht die niet de laatste is.
Dit is de foutmelding die ik krijg wanneer ik dat probeer te doen in SQL Server:
SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;
Resultaat:
Msg 156, Level 15, State 1, Line 4 Incorrect syntax near the keyword 'UNION'.
Daarom, als we de resultaten willen bestellen, moeten we zoiets als dit doen:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;
UNION
toepassen naar de Meer dan twee zoekopdrachten
De vorige voorbeelden combineerden resultaten van twee verschillende zoekopdrachten, maar niets houdt u tegen om meer toe te voegen. Je kunt het desgewenst gebruiken om de resultaten van veel zoekopdrachten te combineren.
Als we bijvoorbeeld ook een Birds
. hadden tafel, we zouden dit kunnen doen:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;
Normalisatie
De voorbeelden op deze pagina plaatsen katten en honden in twee aparte tabellen. De reden dat ik dit deed, is omdat het een duidelijke en beknopte manier is om te illustreren hoe UNION
werkt.
In de praktijk kun je deze in dezelfde tabel hebben, bijvoorbeeld Pets
, neem dan een aparte PetTypes
tafel (of iets dergelijks). Dit staat bekend als normalisatie en is de manier waarop relationele databases gewoonlijk worden ontworpen.
U kunt dan een join uitvoeren op deze tabellen om desgewenst gegevens te retourneren.