sql >> Database teknologi >  >> RDS >> Database

SQL UNION-klausul for begyndere

I SQL er UNION klausul sammenkæder resultaterne af to forespørgsler til et enkelt resultatsæt.

Du kan bruge UNION klausul med eller uden ALL argument:

  • UNION ALL – Inkluderer dubletter.
  • UNION – Udelukker dubletter.

Nedenfor er nogle grundlæggende eksempler for at demonstrere, hvordan det virker.

Eksempeltabeller

Antag, at vi har to tabeller:Cats og Dogs

Cats

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
| 1002    | Fetch     |
+---------+-----------+

Vi kan bruge en SELECT sætning med en UNION klausul for at kombinere resultaterne fra begge tabeller til ét resultatsæt.

Eksempel med UNION ALL

Lad os først bruge UNION ALL så det inkluderer dubletter.

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultat:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

I dette tilfælde returneres syv rækker. Vi kan se, at "Fetch" returneres to gange. Dette skyldes, at der er to hunde ved navn Fetch.

Der er også en kat og en hund med samme navn:Fluffy.

Bemærk, at jeg brugte et kolonnealias til at navngive feltet, der returneres af operationen. Hvis jeg ikke havde gjort det, ville resultatet have brugt kolonnenavnene fra den første forespørgsel. I så fald ville kolonneoverskriften have heddet DogName i stedet for PetName .

SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Resultat:

+-----------+
| DogName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

Dette kan være acceptabelt eller ikke, afhængigt af de data, du returnerer i din forespørgsel. I vores tilfælde er det ikke passende, fordi ikke alle resultater er hunde.

Eksempel med UNION

Lad os se, hvad der sker, når vi fjerner ALL argument.

SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;

Resultat:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Meow      |
| Scratch   |
| Wag       |
+-----------+
(5 rows affected)

Denne gang returneres kun fem rækker. Begge dubletter fjernes.

UNION vs DISTINCT

Bemærk, at dette er anderledes end at anvende DISTINCT til hver enkelt SELECT udmelding. Hvis vi havde gjort det, ville Fluffy være blevet returneret to gange, fordi ALL ville kun gælde for SELECT erklæring om, at det bliver anvendt imod (ikke til de sammenkædede resultater).

Her er et eksempel for at illustrere, hvad jeg mener.

SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;

Resultat:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fluffy    |
| Meow      |
| Scratch   |
+-----------+
(6 rows affected)

Alle forespørgsler skal returnere det samme antal kolonner

Når du bruger UNION klausul skal hver forespørgsel have det samme antal kolonner, og de skal være i samme rækkefølge.

Hvis ikke, får du en fejl.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;

Resultat:

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.

Det er den fejl, som SQL Server returnerer, når der bruges et ulige antal kolonner. Denne særlige fejl indikerer, at den samme begrænsning også gælder for INTERSECT og EXCEPT operatører. Den fejlmeddelelse, du modtager, kan være anderledes, afhængigt af dit DBMS.

Datatyper skal være kompatible

Ud over at kræve det samme antal kolonner, skal disse kolonner have en kompatibel datatype.

De behøver ikke nødvendigvis at være af samme datatype, men de skal være kompatible. Det vil sige, at de skal være kompatible gennem implicit konvertering. Hvis datatyperne ikke stemmer overens, skal DBMS være i stand til at udføre en implicit konvertering, så de matcher.

Hvis ikke, får du en fejl.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;

Resultat:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Meow' to data type int.

Bestilling af resultaterne

Hvis du vil sortere resultaterne med ORDER BY klausul, skal du sætte den på den sidste forespørgsel. Du kan ikke placere en separat ORDER BY klausul på hver forespørgsel, eller for den sags skyld enhver forespørgsel, der ikke er den sidste.

Her er fejlen, jeg får, når jeg prøver at gøre det i SQL Server:

SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;

Resultat:

Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'UNION'.

Derfor, hvis vi vil bestille resultaterne, bliver vi nødt til at gøre sådan noget:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;

Anvender UNION til Mere end to forespørgsler

De tidligere eksempler kombinerede resultater fra to forskellige forespørgsler, men der er intet, der forhindrer dig i at tilføje flere. Du kan bruge det til at kombinere resultaterne af mange forespørgsler, hvis det kræves.

For eksempel, hvis vi også havde en Birds tabel, kunne vi gøre dette:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;

Normalisering

Eksemplerne på denne side placerer katte og hunde i to separate tabeller. Grunden til, at jeg gjorde dette, er, fordi det er en klar og kortfattet måde at illustrere, hvordan UNION virker.

I praksis kan du have disse i den samme tabel kaldet, for eksempel Pets , så har en separat PetTypes bord (eller lignende). Dette er kendt som normalisering og er den måde, relationelle databaser normalt er designet på.

Du kan derefter køre en join på disse tabeller for at returnere data efter behov.


  1. 3 måder at liste alle triggere for en given tabel i PostgreSQL

  2. Sådan opretter du transaktionsreplikering

  3. 2nd Quadrant ved PostgresConf US 2018

  4. Oracle:Hvad gør `(+)` i en WHERE-sætning?