SQL : UNION vs UNION ALL

Combiner les résultats de plusieurs SELECT — avec ou sans doublons, INTERSECT et EXCEPT

8
Sections
15+
Exemples
SQL
Standard

SECTION 01

Le principe

📋 Empiler les résultats de plusieurs SELECT

UNION combine les résultats de deux (ou plus) requêtes SELECT en un seul jeu de résultats. Contrairement au JOIN qui combine des colonnes (horizontalement), UNION empile des lignes (verticalement).

— JOIN = combiner des colonnes (horizontal)
— clients.nom | commandes.montant

— UNION = empiler des lignes (vertical)
— résultat du SELECT 1
— +
— résultat du SELECT 2

Règle obligatoire : chaque SELECT dans un UNION doit avoir le même nombre de colonnes et des types compatibles. Les noms de colonnes du résultat viennent du premier SELECT.

SECTION 02

UNION — sans doublons

UNION supprime automatiquement les lignes en double dans le résultat combiné :

— Toutes les villes (clients + fournisseurs), sans doublons
SELECT ville FROM clients
UNION
SELECT ville FROM fournisseurs;

— clients.ville : Paris, Lyon, Paris, Marseille
— fournisseurs.ville : Lyon, Bordeaux, Paris

— Résultat UNION :
— Paris
— Lyon
— Marseille
— Bordeaux
— → 4 lignes (doublons Paris et Lyon supprimés)

Pour supprimer les doublons, UNION effectue un tri implicite (ou un hash) sur toutes les colonnes. C’est une opération coûteuse sur de gros volumes. Si tu n’as pas besoin de dédupliquer, utilise UNION ALL.

SECTION 03

UNION ALL — avec doublons

UNION ALL garde toutes les lignes, y compris les doublons :

— Toutes les villes, AVEC doublons
SELECT ville FROM clients
UNION ALL
SELECT ville FROM fournisseurs;

— Résultat UNION ALL :
— Paris
— Lyon
— Paris
— Marseille
— Lyon
— Bordeaux
— Paris
— → 7 lignes (tout est gardé)

— Combiner les ventes de deux tables (historique + actuel)
SELECT id, client, montant, date FROM ventes_2024
UNION ALL
SELECT id, client, montant, date FROM ventes_2025;

— Enchaîner plus de 2 SELECT
SELECT nom, ‘client’ AS type FROM clients
UNION ALL
SELECT nom, ‘fournisseur’ FROM fournisseurs
UNION ALL
SELECT nom, ’employe’ FROM employes;

Règle de performance : utilise UNION ALL par défaut. N’utilise UNION (sans ALL) que si tu as réellement besoin de supprimer les doublons. UNION ALL est toujours plus rapide car il ne fait aucun tri ni comparaison.

SECTION 04

Tableau comparatif

Critère UNION UNION ALL
Doublons Supprimés Conservés
Performance ⚠️ Plus lent (tri/hash pour dédupliquer) ✅ Plus rapide (simple concaténation)
Nombre de lignes ≤ somme des deux SELECT = somme des deux SELECT
Usage Quand les doublons posent problème Cas par défaut (logs, historiques…)

SECTION 05

INTERSECT et EXCEPT

🔀 Les autres opérateurs ensemblistes
— INTERSECT — lignes communes aux deux SELECT
SELECT ville FROM clients
INTERSECT
SELECT ville FROM fournisseurs;
— Paris, Lyon (villes en commun)

— EXCEPT (ou MINUS en Oracle) — lignes du 1er SELECT absentes du 2nd
SELECT ville FROM clients
EXCEPT
SELECT ville FROM fournisseurs;
— Marseille (ville client mais pas fournisseur)

— Clients qui n’ont jamais commandé (alternative à NOT EXISTS)
SELECT id FROM clients
EXCEPT
SELECT client_id FROM commandes;

Opérateur Retourne Équivalent ensembliste
UNION Toutes les lignes (sans doublons) A ∪ B
UNION ALL Toutes les lignes (avec doublons) Concaténation
INTERSECT Lignes communes A ∩ B
EXCEPT Lignes du 1er absentes du 2nd A \ B

⚠️ INTERSECT et EXCEPT ne sont pas supportés en MySQL avant la version 8.0.31. En MySQL plus ancien, utilise des JOIN ou EXISTS pour obtenir le même résultat.

SECTION 06

Cas d’usage courants

📦 Combiner des tables partitionnées
— Tables de logs partitionnées par mois
SELECT * FROM logs_2025_01
UNION ALL
SELECT * FROM logs_2025_02
UNION ALL
SELECT * FROM logs_2025_03;
🏷️ Ajouter une colonne de type / source
— Liste unifiée de contacts avec leur source
SELECT nom, email, ‘client’ AS source FROM clients
UNION ALL
SELECT nom, email, ‘prospect’ FROM prospects
UNION ALL
SELECT nom, email, ‘partenaire’ FROM partenaires
ORDER BY nom; — ORDER BY s’applique au résultat final
📊 Émuler FULL OUTER JOIN en MySQL
— MySQL ne supporte pas FULL OUTER JOIN
— Solution : LEFT JOIN UNION RIGHT JOIN
SELECT c.nom, co.produit
FROM clients c
LEFT JOIN commandes co ON c.id = co.client_id

UNION

SELECT c.nom, co.produit
FROM clients c
RIGHT JOIN commandes co ON c.id = co.client_id;

🔢 ORDER BY et LIMIT sur un UNION
— ORDER BY s’applique au résultat combiné (à la fin)
SELECT nom, montant FROM ventes_2024
UNION ALL
SELECT nom, montant FROM ventes_2025
ORDER BY montant DESC
LIMIT 10;

— Pour trier CHAQUE SELECT individuellement, utilise des sous-requêtes :
(SELECT nom, montant FROM ventes_2024 ORDER BY montant DESC LIMIT 5)
UNION ALL
(SELECT nom, montant FROM ventes_2025 ORDER BY montant DESC LIMIT 5);

Sans parenthèses, ORDER BY et LIMIT s’appliquent au résultat final du UNION. Avec parenthèses autour de chaque SELECT, tu peux trier et limiter chaque partie individuellement.

SECTION 07

Erreurs fréquentes

Erreur Problème Solution
Nombre de colonnes différent Erreur : each UNION query must have same number of columns Ajouter des colonnes NULL ou constantes pour aligner
Types incompatibles Conversion implicite inattendue Utiliser CAST pour homogénéiser
UNION au lieu de UNION ALL Doublons légitimes supprimés + lent Utiliser UNION ALL par défaut
ORDER BY au mauvais endroit Erreur de syntaxe ou tri sur un seul SELECT Mettre ORDER BY à la fin du dernier UNION
Confondre UNION et JOIN UNION empile verticalement, JOIN combine horizontalement JOIN pour lier des tables, UNION pour empiler

SECTION 08

Questions fréquentes

UNION vs JOIN — quelle différence ?
JOIN combine des colonnes de tables liées (horizontal). UNION empile des lignes de requêtes indépendantes (vertical). JOIN lie deux tables par une clé. UNION fusionne deux ensembles de résultats qui ont la même structure.
Peut-on faire un UNION de plus de 2 SELECT ?
Oui, tu peux enchaîner autant de UNION (ou UNION ALL) que tu veux : SELECT … UNION ALL SELECT … UNION ALL SELECT …. Il n’y a pas de limite pratique au nombre de SELECT dans un UNION.
Quel est le nom des colonnes dans le résultat ?
Les noms de colonnes du résultat sont ceux du premier SELECT. Les alias du 2e, 3e SELECT… sont ignorés pour le nommage. Utilise des alias clairs dans le premier SELECT.
UNION ALL est-il toujours plus rapide ?
Oui, toujours. UNION ALL fait un simple append des résultats. UNION doit en plus comparer toutes les lignes pour éliminer les doublons (tri ou hash). Sur de petites tables la différence est négligeable, mais sur des millions de lignes elle est significative.

UNION vs UNION ALL en SQL — Combiner des résultats

Référence : sql.sh UNION