sql >> Database >  >> RDS >> Database

SQL UNION-clausule voor beginners

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.


  1. ORA-4031 fouten met Direct NFS

  2. Dynamische gegevensmaskering in SQL Server voor geavanceerde gebruikers

  3. Waarom in MySQL-query's join gebruiken in plaats van waar?

  4. Beste type indexering als er een LIKE-clausule is