SQL DISTINCT : supprimer les doublons
Quand on affiche la ville de chaque client, la même ville revient des dizaines de fois. Pour obtenir la liste des valeurs différentes, on ajoute DISTINCT juste après SELECT.
Syntaxe
SELECT DISTINCT colonne1, colonne2
FROM table;Comment ça marche
DISTINCT supprime les lignes en double du résultat. Point important : il porte sur la ligne entière, pas sur une seule colonne. Avec SELECT DISTINCT ville, age, deux lignes ne sont des doublons que si la ville et l'âge sont identiques.
Compter les valeurs différentes
COUNT(DISTINCT colonne) compte le nombre de valeurs différentes d'une colonne, en ignorant les NULL.
DISTINCT ou GROUP BY ?
SELECT DISTINCT ville FROM clients et SELECT ville FROM clients GROUP BY ville donnent le même résultat. On utilise DISTINCT pour dédoublonner, et GROUP BY quand on veut aussi calculer quelque chose par groupe (un nombre, une somme…).
Schéma
| prenom | ville |
|---|---|
| Léa | Lyon |
| Hugo | Paris |
| Inès | Lyon |
| Adam | Paris |
| ville |
|---|
| Lyon |
| Paris |
Schéma simplifié pour illustrer le principe. Les exemples ci-dessous utilisent la vraie base d'exercices de SQL Quest (une boutique en ligne fictive : voir le schéma complet).
Exemples avec leurs résultats
1. Lister les valeurs différentes
Les villes où habitent nos clients, sans doublon.
SELECT DISTINCT ville
FROM clients
ORDER BY ville; Essayer dans le bac à sable| ville |
|---|
| Bordeaux |
| Bruxelles |
| Casablanca |
| Genève |
| Lille |
| Lyon |
| Marseille |
| Montréal |
| Nantes |
| Paris |
12 lignes au total · 10 affichées
2. Compter les valeurs différentes
Combien de villes différentes, et combien de clients au total ?
SELECT COUNT(DISTINCT ville) AS villes, COUNT(*) AS clients
FROM clients; Essayer dans le bac à sable| villes | clients |
|---|---|
| 12 | 120 |
1 ligne au total
3. DISTINCT sur deux colonnes
Les couples (département, poste) différents parmi les employés.
SELECT DISTINCT departement, poste
FROM employes
ORDER BY departement; Essayer dans le bac à sable| departement | poste |
|---|---|
| Direction | PDG |
| IT | Directrice technique |
| IT | Développeur |
| RH | Responsable RH |
| RH | Chargé RH |
| Ventes | Directeur commercial |
| Ventes | Commercial |
7 lignes au total
Les erreurs fréquentes
Croire que DISTINCT porte sur une seule colonne
Ici, chaque ligne est différente car l'id change : DISTINCT ne supprime rien.
SELECT DISTINCT id, ville FROM clients;SELECT DISTINCT ville FROM clients;Écrire DISTINCT au milieu du SELECT
DISTINCT se place juste après SELECT, pas devant une colonne en particulier (sauf dans COUNT(DISTINCT …)).
SELECT prenom, DISTINCT ville FROM clients;SELECT DISTINCT ville FROM clients;Masquer un problème de jointure
Des doublons inattendus après une jointure signalent souvent une condition ON incomplète. DISTINCT les cache sans corriger la cause : vérifiez d'abord votre jointure.
SELECT DISTINCT c.nom FROM clients c JOIN commandes o;SELECT DISTINCT c.nom FROM clients c JOIN commandes o ON o.client_id = c.id;Exercices
Essayez d'écrire la requête vous-même avant d'ouvrir la solution.
Défi 1. Affichez la liste des statuts de commande différents.
Voir une solution
SELECT DISTINCT statut FROM commandes;| statut |
|---|
| annulée |
| en cours |
| expédiée |
| livrée |
4 lignes au total
Essayer dans le bac à sableDéfi 2. Combien de clients différents ont passé au moins une commande ?
Voir une solution
SELECT COUNT(DISTINCT client_id) FROM commandes;| COUNT(DISTINCT client_id) |
|---|
| 110 |
1 ligne au total
Essayer dans le bac à sableLes exercices interactifs sont corrigés automatiquement, avec un prof qui explique vos erreurs. Une leçon résumée reste affichée à côté de l'éditeur.
Questions fréquentes
DISTINCT trie-t-il les résultats ?
Pas forcément. L'ordre peut sembler trié, mais il n'est pas garanti : ajoutez ORDER BY si l'ordre compte.
DISTINCT prend-il en compte les NULL ?
Oui, SELECT DISTINCT considère tous les NULL comme identiques et en garde un seul. COUNT(DISTINCT colonne), lui, ignore les NULL.
DISTINCT ralentit-il une requête ?
Un peu, car la base doit comparer les lignes entre elles. Sur de petites tables, c'est négligeable.