Dans MySQL, l'UNION
La clause combine les résultats de plusieurs requêtes en un seul jeu de résultats.
Exemple
Supposons que nous ayons les tables suivantes :
SELECT * FROM Teachers;
SELECT * FROM Students;
Résultat :
+-----------+-------------+ | 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 | +-----------+-------------+
Nous pouvons insérer le UNION
clause entre ces deux SELECT
instructions pour renvoyer tous les enseignants et élèves :
SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;
Résultat :
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
Les noms de colonne sont extraits du premier SELECT
déclaration.
Par défaut, le UNION
clause applique implicitement un DISTINCT
opération. En d'autres termes, il ne renvoie que des valeurs distinctes par défaut. Ainsi, les résultats ci-dessus contiennent un seul chacun de Warren, Cathy et Bill. Ceci malgré le fait que les tables combinées contiennent en fait deux Warrens, deux Cathys et trois Bills (il y a deux enseignants appelés Cathy, un enseignant et un client appelé Warren, et deux appelés Bill, ainsi qu'un étudiant appelé Bill).
Voici un exemple qui utilise explicitement le DISTINCT
clause :
SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;
Résultat :
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | Faye | | Jet | | Spike | | Ein | +-------------+
Nous obtenons donc le même résultat que nous avons obtenu sans le DISTINCT
clause.
Inclure les doublons
Nous pouvons utiliser le ALL
mot-clé pour inclure les valeurs en double dans les résultats :
SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;
Résultat :
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Cathy | | Bill | | Bill | | Faye | | Jet | | Spike | | Ein | | Warren | | Bill | +-------------+
Cette fois, nous avons eu douze lignes au lieu des huit que nous avions dans notre premier exemple.
Nous pouvons voir que les deux Cathys ont été retournées et que les trois Bills ont été retournés.
TABLE
Déclarations
Depuis MySQL 8.0.19, nous pouvons utiliser le UNION
clause avec la TABLE
déclaration.
Voici un exemple :
TABLE Teachers
UNION
TABLE Students;
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
C'est l'équivalent de la requête suivante :
SELECT * FROM Teachers
UNION
SELECT * FROM Students;
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 1 | Warren | | 2 | Ben | | 3 | Cathy | | 4 | Cathy | | 5 | Bill | | 6 | Bill | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 4 | Ein | | 5 | Warren | +-----------+-------------+
Vous remarquerez que ces instructions renvoient plus de lignes que dans notre premier exemple précédent. En effet, nous sélectionnons toutes les colonnes du tableau, ce qui entraîne des non-doublons là où il y avait auparavant un doublon. Par exemple, deux enseignants appelés Bill sont renvoyés ici alors qu'un seul a été renvoyé dans l'exemple précédent. C'est parce que le TeacherId
les colonnes contiennent des valeurs différentes, donc les lignes ne sont pas des doublons.
Utilisation de ORDER BY
Clause dans les requêtes Union
Nous pouvons utiliser le ORDER BY
clause dans chaque SELECT
déclaration et/ou sur le combiné UNION
requête.
Dans chaque SELECT
Déclaration
Lorsque nous utilisons le ORDER BY
clause dans le SELECT
individuel déclarations au sein d'une UNION
requête, nous devons joindre chaque SELECT
déclaration entre parenthèses :
(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 4 | Ein | +-----------+-------------+
Notez que lorsque nous faisons cela, cela ne commande pas réellement les résultats pour la sortie. Il ordonne uniquement les résultats dans le but de déterminer le sous-ensemble des lignes sélectionnées à récupérer lors de l'application de la LIMIT
clause.
Par conséquent, en utilisant ORDER BY
sans la LIMIT
la clause n'a aucun effet sur la sortie.
Dans l'ensemble UNION
Requête
Nous pouvons également utiliser un ORDER BY
clause sur l'ensemble de la requête, de sorte que toute la sortie est ordonnée ensemble.
Dans cet exemple, nous reprenons l'exemple précédent et ordonnons les résultats combinés :
(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 4 | Ein | | 5 | Bill | | 6 | Bill | | 2 | Ben | +-----------+-------------+
Même lorsque vous n'utilisez pas le ORDER BY
clause dans chaque SELECT
instruction, chaque SELECT
doit toujours être entre parenthèses, et le ORDER BY
clause (ou toute clause LIMIT
clause) doit être après la dernière.
(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
Attention, omettre les parenthèses produit le même résultat que celui avec parenthèses :
SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;
Résultat :
+-----------+-------------+ | TeacherId | TeacherName | +-----------+-------------+ | 2 | Ben | | 5 | Bill | | 6 | Bill | | 3 | Cathy | | 4 | Cathy | | 4 | Ein | | 1 | Faye | | 2 | Jet | | 3 | Spike | | 1 | Warren | | 5 | Warren | +-----------+-------------+
Notez que si une colonne à trier utilise un alias, cette colonne doit être référencée par son alias (et non par le nom de la colonne).
Exemple :
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;
Résultat :
+--------+ | t | +--------+ | Ben | | Bill | | Cathy | | Ein | | Faye | | Jet | | Spike | | Warren | +--------+
Voici ce qui se passe si nous n'utilisons pas l'alias :
(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;
Résultat :
ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'
Nombre de colonnes
Le nombre de colonnes renvoyées par chaque SELECT
l'énoncé doit être le même. Par conséquent, nous ne pouvons pas effectuer les actions suivantes :
SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;
Résultat :
ERROR 1222 (21000): The used SELECT statements have a different number of columns
Types de données
Colonnes sélectionnées répertoriées dans les positions correspondantes de chaque SELECT
l'instruction doit avoir le même type de données. Cependant, si ce n'est pas le cas, les types et longueurs des colonnes dans UNION
résultat prend en compte les valeurs récupérées par tous les SELECT
déclarations.
Voici ce qui se passe si nous essayons de combiner le TeacherName
colonne avec le StudentId
colonne :
SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;
Résultat :
+-------------+ | TeacherName | +-------------+ | Warren | | Ben | | Cathy | | Bill | | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +-------------+
Certains autres RDBMS produiraient une erreur dans cette instance, mais MySQL parvient à produire une sortie sans erreur.