sql >> Database >  >> RDS >> Mysql

MySQL UNION-clausule

In MySQL is de UNION clausule combineert de resultaten van meerdere zoekopdrachten in een enkele resultaatset.

Voorbeeld

Stel dat we de volgende tabellen hebben:

SELECT * FROM Teachers;
SELECT * FROM Students;

Resultaat:

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

We kunnen de UNION . invoegen clausule tussen die twee SELECT verklaringen om alle docenten en studenten terug te geven:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Resultaat:

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

De kolomnamen zijn afkomstig uit de eerste SELECT verklaring.

Standaard is de UNION clausule past impliciet een DISTINCT toe operatie. Met andere woorden, het retourneert standaard alleen afzonderlijke waarden. Dus de bovenstaande resultaten bevatten slechts één van Warren, Cathy en Bill. Dit ondanks het feit dat de gecombineerde tabellen eigenlijk twee Warrens, twee Cathys en drie Bills bevatten (er zijn twee docenten genaamd Cathy, een docent en een klant genaamd Warren, en twee genaamd Bill, evenals een student genaamd Bill).

Hier is een voorbeeld dat expliciet de DISTINCT . gebruikt clausule:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Resultaat:

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

We krijgen dus hetzelfde resultaat als zonder de DISTINCT clausule.

Duplicaten opnemen

We kunnen de ALL . gebruiken zoekwoord om dubbele waarden in de resultaten op te nemen:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Resultaat:

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

Deze keer kregen we twaalf rijen in plaats van de acht die we in ons eerste voorbeeld kregen.

We kunnen zien dat beide Cathy's zijn geretourneerd en alle drie de rekeningen zijn geretourneerd.

TABLE Verklaringen

Vanaf MySQL 8.0.19 kunnen we de UNION . gebruiken clausule met de TABLE uitspraak.

Hier is een voorbeeld:

TABLE Teachers
UNION
TABLE Students;

Resultaat:

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

Dat is het equivalent van de volgende vraag:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Resultaat:

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

U zult merken dat deze instructies meer rijen retourneren dan in ons eerste voorbeeld eerder. Dat komt omdat we alle kolommen in de tabel selecteren, wat resulteert in niet-duplicaten waar er eerder een duplicaat was. Er worden hier bijvoorbeeld twee leraren met de naam Bill geretourneerd, terwijl er in het eerdere voorbeeld slechts één werd geretourneerd. Dat komt omdat de TeacherId kolommen bevatten verschillende waarden, daarom zijn de rijen geen duplicaten.

De ORDER BY gebruiken Clausule in Union Queries

We kunnen de ORDER BY . gebruiken clausule in elke SELECT statement en/of op de gecombineerde UNION vraag.

In elke SELECT Verklaring

Wanneer we de ORDER BY . gebruiken clausule in de individuele SELECT verklaringen binnen een UNION query, moeten we elke SELECT verklaring tussen haakjes:

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

Resultaat:

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

Houd er rekening mee dat wanneer we dit doen, de resultaten voor de uitvoer niet echt worden geordend. Het bestelt de resultaten alleen om de subset van de geselecteerde rijen te bepalen die moet worden opgehaald bij het toepassen van de LIMIT clausule.

Gebruik daarom ORDER BY zonder de LIMIT clausule heeft geen effect op de uitvoer.

Over het geheel genomen UNION Zoekopdracht

We kunnen ook een ORDER BY . gebruiken clausule op de hele query, zodat de hele uitvoer samen wordt besteld.

In dit voorbeeld nemen we het vorige voorbeeld en rangschikken we de gecombineerde resultaten:

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

Resultaat:

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

Zelfs als u de ORDER BY . niet gebruikt clausule binnen elke SELECT statement, elke SELECT statement moet nog steeds tussen haakjes staan, en de ORDER BY clausule (of een LIMIT clausule) moet na de laatste staan.

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

Resultaat:

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

Let op, het weglaten van de haakjes levert hetzelfde resultaat op als het resultaat met haakjes:

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

Resultaat:

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

Houd er rekening mee dat als een te sorteren kolom een ​​alias gebruikt, naar die kolom moet worden verwezen door zijn alias (niet de kolomnaam).

Voorbeeld:

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

Resultaat:

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

Dit is wat er gebeurt als we de alias niet gebruiken:

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

Resultaat:

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

Aantal kolommen

Het aantal kolommen dat wordt geretourneerd door elke SELECT verklaring moet hetzelfde zijn. Daarom kunnen we het volgende niet doen:

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

Resultaat:

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

Gegevenstypen

Geselecteerde kolommen weergegeven in corresponderende posities van elke SELECT statement moet hetzelfde gegevenstype hebben. Als dit echter niet het geval is, worden de typen en lengtes van de kolommen in de UNION resultaat houdt rekening met de waarden die zijn opgehaald door alle SELECT verklaringen.

Dit is wat er gebeurt als we proberen de TeacherName te combineren kolom met de StudentId kolom:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Resultaat:

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

Sommige andere RDBMS'en zouden in dit geval een fout produceren, maar MySQL slaagt erin om uitvoer zonder fouten te produceren.


  1. Tabel als argument van een PostgreSQL-functie

  2. Een PostgreSQL-database controleren

  3. SQL ORDER BY:De 5 do's en don'ts om gegevens als een professional te sorteren

  4. PostgreSQL-tabel maken als deze niet bestaat