Database
 sql >> Base de données >  >> RDS >> Database

Clause SQL UNION pour les débutants

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.