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

MySQL UNION-klausul

I MySQL er UNION klausul kombinerer resultaterne fra flere forespørgsler til et enkelt resultatsæt.

Eksempel

Antag, at vi har følgende tabeller:

SELECT * FROM Teachers;
SELECT * FROM Students;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
+-----------+-------------+

+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
|         6 | Bill        |
+-----------+-------------+

Vi kan indsætte UNION klausul mellem disse to SELECT erklæringer for at returnere alle lærere og elever:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Resultat:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Kolonnenavnene er taget fra den første SELECT erklæring.

Som standard er UNION klausul anvender implicit en DISTINCT operation. Med andre ord returnerer det kun distinkte værdier som standard. Så ovenstående resultater indeholder kun én af hver af Warren, Cathy og Bill. Dette er på trods af, at de kombinerede tabeller faktisk indeholder to Warrens, to Cathys og tre Bills (der er to lærere, der hedder Cathy, en lærer og en kunde, der hedder Warren, og to, der hedder Bill, samt en elev, der hedder Bill).

Her er et eksempel, der eksplicit bruger DISTINCT klausul:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Resultat:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Så vi får det samme resultat, som vi fik uden DISTINCT klausul.

Medtag dubletter

Vi kan bruge ALL søgeord for at inkludere duplikerede værdier i resultaterne:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Resultat:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Cathy       |
| Bill        |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
| Warren      |
| Bill        |
+-------------+

Denne gang fik vi tolv rækker i stedet for de otte, som vi fik i vores første eksempel.

Vi kan se, at begge Cathys blev returneret, og alle tre regninger blev returneret.

TABLE Udtalelser

Fra MySQL 8.0.19 kan vi bruge UNION klausul med TABLE udmelding.

Her er et eksempel:

TABLE Teachers
UNION
TABLE Students;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Det svarer til følgende forespørgsel:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Du vil bemærke, at disse udsagn returnerer flere rækker end i vores første eksempel tidligere. Det skyldes, at vi udvælger alle kolonner i tabellen, hvilket resulterer i ikke-duplikater, hvor der tidligere var en dublet. For eksempel returneres to lærere kaldet Bill her, mens kun én blev returneret i det tidligere eksempel. Det er fordi TeacherId kolonner indeholder forskellige værdier, derfor er rækkerne ikke dubletter.

Brug af ORDER BY Klausul i Union Queries

Vi kan bruge ORDER BY klausul i hver SELECT sætning og/eller på den kombinerede UNION forespørgsel.

I hver SELECT Erklæring

Når vi bruger ORDER BY klausul i den individuelle SELECT udsagn i en UNION forespørgsel, skal vi vedlægge hver SELECT sætning inden for parentes:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         4 | Ein         |
+-----------+-------------+

Bemærk, at når vi gør dette, bestiller det faktisk ikke resultaterne for outputtet. Den bestiller kun resultaterne med det formål at bestemme delmængden af ​​de valgte rækker, der skal hentes ved anvendelse af LIMIT klausul.

Brug derfor ORDER BY uden LIMIT klausul har ingen effekt på outputtet.

I det hele taget UNION Forespørgsel

Vi kan også bruge en ORDER BY klausul på hele forespørgslen, så hele outputtet er ordnet sammen.

I dette eksempel tager vi det foregående eksempel og bestiller de kombinerede resultater:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         4 | Ein         |
|         5 | Bill        |
|         6 | Bill        |
|         2 | Ben         |
+-----------+-------------+

Selv når du ikke bruger ORDER BY klausul inden for hver SELECT sætning, hver SELECT sætningen skal stadig stå i parentes, og ORDER BY klausul (eller en hvilken som helst LIMIT klausul) skal være efter den sidste.

(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Husk, at udeladelse af parentes giver det samme resultat som det med parentes:

SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;

Resultat:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Bemærk, at hvis en kolonne, der skal sorteres, bruger et alias, skal den kolonne refereres til ved sit alias (ikke kolonnenavnet).

Eksempel:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;

Resultat:

+--------+
| t      |
+--------+
| Ben    |
| Bill   |
| Cathy  |
| Ein    |
| Faye   |
| Jet    |
| Spike  |
| Warren |
+--------+

Her er hvad der sker, hvis vi ikke bruger aliaset:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;

Resultat:

ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'

Antal kolonner

Antallet af kolonner, der returneres af hver SELECT udsagnet skal være det samme. Derfor kan vi ikke gøre følgende:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;

Resultat:

ERROR 1222 (21000): The used SELECT statements have a different number of columns

Datatyper

Valgte kolonner opført i tilsvarende positioner for hver SELECT sætningen skal have samme datatype. Men hvis de ikke gør det, typerne og længderne af kolonnerne i UNION resultat tage højde for værdierne hentet af alle SELECT udsagn.

Her er, hvad der sker, hvis vi prøver at kombinere TeacherName kolonne med StudentId kolonne:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Resultat:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| 1           |
| 2           |
| 3           |
| 4           |
| 5           |
| 6           |
+-------------+

Nogle andre RDBMS'er ville producere en fejl i dette tilfælde, men MySQL formår at producere output uden fejl.


  1. Hvordan kan jeg bruge en MySql brugerdefineret variabel i en .NET MySqlCommand?

  2. Bedste måde at køre Oracle-forespørgsler med jævne mellemrum

  3. Sql*plus returnerer altid exit-kode 0?

  4. Vælg kolonner fra resultatsæt af lagret procedure