sql >> Databasteknik >  >> RDS >> Mysql

MySQL UNION-klausul

I MySQL, UNION sats kombinerar resultaten från flera frågor till en enda resultatuppsättning.

Exempel

Anta att vi har följande 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 infoga UNION klausul mellan dessa två SELECT uttalanden för att returnera alla lärare och elever:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Resultat:

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

Kolumnnamnen är hämtade från den första SELECT uttalande.

Som standard är UNION satsen tillämpar implicit en DISTINCT drift. Med andra ord returnerar den endast distinkta värden som standard. Så ovanstående resultat innehåller bara ett vardera av Warren, Cathy och Bill. Detta trots att de kombinerade tabellerna faktiskt innehåller två Warrens, två Cathys och tre Bills (det finns två lärare som heter Cathy, en lärare och en kund som heter Warren, och två som heter Bill, samt en elev som heter Bill).

Här är ett exempel som uttryckligen använder 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 samma resultat som vi fick utan DISTINCT klausul.

Inkludera dubbletter

Vi kan använda ALL sökord för att inkludera dubbletter av värden i resultaten:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Resultat:

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

Den här gången fick vi tolv rader istället för de åtta som vi fick i vårt första exempel.

Vi kan se att båda Cathys returnerades och alla tre räkningarna returnerades.

TABLE Uttalanden

Från MySQL 8.0.19 kan vi använda UNION sats med TABLE påstående.

Här är ett exempel:

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 motsvarar följande fråga:

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 kommer att märka att dessa påståenden returnerar fler rader än i vårt första exempel tidigare. Det beror på att vi väljer alla kolumner i tabellen, vilket resulterar i icke-dubbletter där det tidigare fanns en dubblett. Till exempel returneras två lärare som heter Bill här medan endast en returnerades i det tidigare exemplet. Det beror på att TeacherId kolumner innehåller olika värden, därför är raderna inte dubbletter.

Använda ORDER BY Klausul i Union Queries

Vi kan använda ORDER BY sats i varje SELECT uttalande och/eller på den kombinerade UNION fråga.

I varje SELECT Uttalande

När vi använder ORDER BY sats i den individuella SELECT uttalanden inom en UNION fråga måste vi bifoga varje SELECT uttalande inom 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         |
+-----------+-------------+

Observera att när vi gör detta ordnar det faktiskt inte resultaten för utdata. Den ordnar bara resultaten i syfte att bestämma delmängden av de valda raderna som ska hämtas när LIMIT tillämpas klausul.

Använd därför ORDER BY utan LIMIT klausulen har ingen effekt på utdata.

I det hela UNION Fråga

Vi kan också använda en ORDER BY sats på hela frågan, så att hela utdata ordnas tillsammans.

I det här exemplet tar vi det föregående exemplet och beställer de kombinerade resultaten:

(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         |
+-----------+-------------+

Även när du inte använder ORDER BY sats inom varje SELECT sats, varje SELECT satsen ska fortfarande stå inom parentes och ORDER BY klausul (eller någon LIMIT sats) bör vara efter den sista.

(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      |
+-----------+-------------+

Tänk på, att utelämna parentesen ger samma resultat som den 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      |
+-----------+-------------+

Observera att om en kolumn som ska sorteras använder ett alias, måste den kolumnen refereras av dess alias (inte kolumnnamnet).

Exempel:

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

Resultat:

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

Så här händer om vi inte använder 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 kolumner

Antalet kolumner som returneras av varje SELECT uttalandet måste vara detsamma. Därför kan vi inte göra följande:

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

Valda kolumner listade i motsvarande positioner för varje SELECT uttalandet ska ha samma datatyp. Men om de inte gör det, typ och längd på kolumnerna i UNION resultatet tar hänsyn till de värden som hämtas av alla SELECT uttalanden.

Här är vad som händer om vi försöker kombinera TeacherName kolumnen med StudentId kolumn:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Resultat:

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

Vissa andra RDBMS skulle ge ett fel i det här fallet, men MySQL lyckas producera utdata utan fel.


  1. 7 sätt att hitta dubbletter av rader i SQL Server samtidigt som du ignorerar en primärnyckel

  2. Hur man får det aktuella datumet i MySQL

  3. Hur ställer jag in ett SQL Server-skripts timeout inifrån skriptet?

  4. Returnera antalet dagar i en månad i MariaDB