Mysql
 sql >> база данни >  >> RDS >> Mysql

Клауза за MySQL UNION

В MySQL, UNION клауза комбинира резултатите от множество заявки в един набор от резултати.

Пример

Да предположим, че имаме следните таблици:

SELECT * FROM Teachers;
SELECT * FROM Students; 

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 1 | Уорън || 2 | Бен || 3 | Кати || 4 | Кати || 5 | Бил || 6 | Сметка |+-----------+-------------++-----------+-------- -----+| StudentId | Име на ученик |+-----------+------------+| 1 | Фей || 2 | Реактивен || 3 | Спайк || 4 | Ein || 5 | Уорън || 6 | Сметка |+-----------+------------+

Можем да вмъкнем UNION клауза между тези две SELECT изявления за връщане на всички учители и ученици:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students; 

Резултат:

+------------+| Име на учителя |+------------+| Уорън || Бен || Кати || Бил || Фей || Реактивен || Спайк || Ein |+------------+

Имената на колоните са взети от първия SELECT изявление.

По подразбиране UNION клаузата имплицитно прилага DISTINCT операция. С други думи, той връща само различни стойности по подразбиране. Така че горните резултати съдържат само по един от Уорън, Кати и Бил. Това е въпреки факта, че комбинираните таблици всъщност съдържат двама Уорън, две Кати и три Била (има двама учители, наречени Кати, учител и клиент, наречен Уорън, и двама, наречени Бил, както и един ученик, наречен Бил).

Ето пример, който изрично използва DISTINCT клауза:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students; 

Резултат:

+------------+| Име на учителя |+------------+| Уорън || Бен || Кати || Бил || Фей || Реактивен || Спайк || Ein |+------------+

Така получаваме същия резултат, който получихме без DISTINCT клауза.

Включване на дубликати

Можем да използваме ALL ключова дума, за да включите дублиращи се стойности в резултатите:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students; 

Резултат:

+------------+| Име на учителя |+------------+| Уорън || Бен || Кати || Кати || Бил || Бил || Фей || Реактивен || Спайк || Ein || Уорън || Сметка |+------------+

Този път получихме дванадесет реда вместо осемте, които получихме в първия ни пример.

Можем да видим, че и двете Кати бяха върнати и трите законопроекта бяха върнати.

TABLE Изявления

От MySQL 8.0.19 можем да използваме UNION клауза с TABLE изявление.

Ето един пример:

TABLE Teachers
UNION
TABLE Students; 

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 1 | Уорън || 2 | Бен || 3 | Кати || 4 | Кати || 5 | Бил || 6 | Бил || 1 | Фей || 2 | Реактивен || 3 | Спайк || 4 | Ein || 5 | Уорън |+-----------+------------+

Това е еквивалент на следната заявка:

SELECT * FROM Teachers
UNION
SELECT * FROM Students; 

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 1 | Уорън || 2 | Бен || 3 | Кати || 4 | Кати || 5 | Бил || 6 | Бил || 1 | Фей || 2 | Реактивен || 3 | Спайк || 4 | Ein || 5 | Уорън |+-----------+------------+

Ще забележите, че тези изрази връщат повече редове, отколкото в първия ни пример по-рано. Това е така, защото избираме всички колони в таблицата, което води до недублиране, където преди е имало дубликат. Например двама учители, наречени Бил, са върнати тук, докато само един е върнат в предишния пример. Това е така, защото TeacherId колоните съдържат различни стойности, следователно редовете не са дублирани.

Използване на ORDER BY Клауза в заявките за съюз

Можем да използваме ORDER BY клауза във всеки SELECT изявление и/или на комбинирания UNION запитване.

Във всеки SELECT Изявление

Когато използваме ORDER BY клауза в отделния SELECT изрази в рамките на UNION заявка, трябва да оградим всеки SELECT изявление в скоби:

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

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 2 | Бен || 5 | Бил || 6 | Бил || 4 | Ein |+-----------+------------+

Имайте предвид, че когато правим това, това всъщност не подрежда резултатите за изхода. Той подрежда резултатите само с цел определяне на подмножеството от избраните редове за извличане при прилагане на LIMIT клауза.

Следователно, използвайте ORDER BY без LIMIT клаузата няма ефект върху изхода.

Като цяло UNION Запитване

Можем също да използваме ORDER BY клауза за цялата заявка, така че целият изход да бъде подреден заедно.

В този пример вземаме предишния пример и подреждаме комбинираните резултати:

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

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 4 | Ein || 5 | Бил || 6 | Бил || 2 | Бен |+-----------+------------+

Дори когато не използвате ORDER BY клауза във всеки SELECT израз, всеки SELECT операторът все още трябва да е в скоби, а ORDER BY клауза (или който и да е LIMIT клауза) трябва да е след последната.

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

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 2 | Бен || 5 | Бил || 6 | Бил || 3 | Кати || 4 | Кати || 4 | Ein || 1 | Фей || 2 | Реактивен || 3 | Спайк || 1 | Уорън || 5 | Уорън |+-----------+------------+

Имайте предвид, че пропускането на скоби води до същия резултат като този със скоби:

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

Резултат:

+-----------+------------+| Идентификатор на учителя | Име на учителя |+-----------+------------+| 2 | Бен || 5 | Бил || 6 | Бил || 3 | Кати || 4 | Кати || 4 | Ein || 1 | Фей || 2 | Реактивен || 3 | Спайк || 1 | Уорън || 5 | Уорън |+-----------+------------+

Имайте предвид, че ако колона, която трябва да бъде сортирана, използва псевдоним, тогава тази колона трябва да бъде посочена от нейния псевдоним (а не името на колоната).

Пример:

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

Резултат:

<пред>+--------+| t |+--------+| Бен || Бил || Кати || Ein || Фей || Реактивен || Спайк || Уорън |+--------+

Ето какво се случва, ако не използваме псевдонима:

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

Резултат:

ГРЕШКА 1054 (42S22):Неизвестна колона „Име на учител“ в „клауза за поръчка“

Брой колони

Броят на колоните, върнати от всеки SELECT изявлението трябва да е същото. Следователно не можем да направим следното:

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

Резултат:

ГРЕШКА 1222 (21000):Използваните изрази SELECT имат различен брой колони

Типове данни

Избрани колони, изброени на съответните позиции на всеки SELECT изявлението трябва да има същия тип данни. Ако обаче не го направят, типовете и дължините на колоните в UNION резултатът взема предвид стойностите, извлечени от всички SELECT изявления.

Ето какво се случва, ако се опитаме да комбинираме TeacherName колона с StudentId колона:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students; 

Резултат:

+------------+| Име на учителя |+------------+| Уорън || Бен || Кати || Бил || 1 || 2 || 3 || 4 || 5 || 6 |+------------+

Някои други RDBMS биха довели до грешка в този случай, но MySQL успява да произведе изход без грешка.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Таблицата е посочена два пъти, и като цел за 'UPDATE' и като отделен източник за данни в mysql

  2. Параметризирана заявка за MySQL с C#

  3. Обявяване на ClusterControl 1.7.5:Разширена поддръжка и поддръжка на клъстер за PostgreSQL 12 и MongoDB 4.2

  4. MySQL добавя дни към дата

  5. Възстановете структурата на таблицата от frm и ibd файлове