En SQL, l'UNION
La clause concatène les résultats de deux requêtes en un seul jeu de résultats.
Vous pouvez utiliser le UNION
clause avec ou sans ALL
argument :
UNION ALL
– Inclut les doublons.UNION
– Exclut les doublons.
Vous trouverez ci-dessous quelques exemples de base pour montrer comment cela fonctionne.
Tableaux d'exemple
Supposons que nous ayons deux tables :Cats
et Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Nous pouvons utiliser un SELECT
déclaration avec un UNION
clause pour combiner les résultats des deux tables en un seul jeu de résultats.
Exemple utilisant UNION ALL
D'abord, utilisons UNION ALL
afin qu'il inclue les doublons.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Résultat :
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
Dans ce cas, sept lignes sont renvoyées. Nous pouvons voir que "Fetch" est retourné deux fois. C'est parce qu'il y a deux chiens nommés Fetch.
Il y a aussi un chat et un chien du même nom :Fluffy.
Notez que j'ai utilisé un alias de colonne pour nommer le champ renvoyé par l'opération. Si je n'avais pas fait cela, le résultat aurait utilisé les noms de colonne de la première requête. Dans ce cas, l'en-tête de colonne aurait été appelé DogName
au lieu de PetName
.
SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Résultat :
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
Cela peut être acceptable ou non, selon les données que vous renvoyez dans votre requête. Dans notre cas, ce n'est pas approprié, car tous les résultats ne sont pas des chiens.
Exemple utilisant UNION
Voyons ce qui se passe lorsque nous supprimons le ALL
arguments.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Résultat :
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Cette fois, seules cinq lignes sont renvoyées. Les deux doublons sont supprimés.
UNION
vs DISTINCT
Notez que cela est différent de l'application de DISTINCT
à chaque SELECT
individuel déclaration. Si nous avions fait cela, Fluffy aurait été renvoyé deux fois, car le ALL
ne s'appliquerait qu'au SELECT
déclaration à laquelle il est appliqué (et non aux résultats concaténés).
Voici un exemple pour illustrer ce que je veux dire.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Résultat :
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
Toutes les requêtes doivent renvoyer le même nombre de colonnes
Lorsque vous utilisez l'UNION
clause, chaque requête doit avoir le même nombre de colonnes et elles doivent être dans le même ordre.
Sinon, vous obtiendrez une erreur.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;
Résultat :
Msg 205, Level 16, State 1, Line 1 All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
C'est l'erreur renvoyée par SQL Server lors de l'utilisation d'un nombre inégal de colonnes. Cette erreur particulière indique que la même restriction s'applique également à INTERSECT
et EXCEPT
les opérateurs. Le message d'erreur que vous recevez peut être différent selon votre SGBD.
Les types de données doivent être compatibles
En plus de nécessiter le même nombre de colonnes, ces colonnes doivent avoir un type de données compatible.
Ils ne doivent pas nécessairement être du même type de données, mais ils devront être compatibles. Autrement dit, ils doivent être compatibles par conversion implicite. Si les types de données ne correspondent pas, le SGBD doit pouvoir effectuer une conversion implicite pour qu'ils correspondent.
Sinon, vous obtiendrez une erreur.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;
Résultat :
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Meow' to data type int.
Ordre des résultats
Si vous voulez trier les résultats avec le ORDER BY
clause, vous devrez la mettre sur la dernière requête. Vous ne pouvez pas mettre un ORDER BY
séparé clause sur chaque requête, ou d'ailleurs, toute requête qui n'est pas la dernière.
Voici l'erreur que j'obtiens en essayant de le faire dans SQL Server :
SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;
Résultat :
Msg 156, Level 15, State 1, Line 4 Incorrect syntax near the keyword 'UNION'.
Par conséquent, si nous voulons ordonner les résultats, nous devrons faire quelque chose comme ceci :
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;
Appliquer UNION
à Plus de deux requêtes
Les exemples précédents combinaient les résultats de deux requêtes différentes, mais rien ne vous empêche d'en ajouter d'autres. Vous pouvez l'utiliser pour combiner les résultats de plusieurs requêtes si nécessaire.
Par exemple, si nous avions aussi un Birds
table, nous pourrions faire ceci :
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;
Normalisation
Les exemples de cette page placent les chats et les chiens dans deux tables distinctes. La raison pour laquelle j'ai fait cela est parce que c'est une manière claire et concise d'illustrer comment UNION
fonctionne.
En pratique, vous pourriez les avoir dans la même table appelée, disons Pets
, puis avoir un PetTypes
séparé tableau (ou similaire). C'est ce qu'on appelle la normalisation et c'est ainsi que les bases de données relationnelles sont généralement conçues.
Vous pouvez ensuite exécuter une jointure sur ces tables pour renvoyer les données nécessaires.