EXCEPT / MINUS – Soustraire des résultats
Bonne lecture et bon apprentissage !
Junior TSAFACK – 08/08/2026
⏱️ Temps de lecture estimé : 4 minutes
Dans le langage SQL, la commande EXCEPT s’utilise entre 2 instructions pour récupérer les enregistrements de la première instruction sans inclure les résultats de la seconde requête. Si un même enregistrement devait être présent dans les résultats des 2 requêtes, il ne sera pas présent dans le résultat final.
Bon à savoir : Cette commande s’appelle différemment selon les Systèmes de Gestion de Base de Données (SGBD) :
EXCEPT: PostgreSQL, SQL Server, SQLite (depuis la version 3.8.3), MySQL (depuis la version 8.0.31)MINUS: Oracle, MySQL (versions antérieures à 8.0.31)
Dès lors, il faut remplacer tout le reste de ce cours par MINUS pour les SGBD correspondants.
Syntaxe
Section titled “Syntaxe”La syntaxe d’une requête SQL est toute simple :
SELECT * FROM table1EXCEPTSELECT * FROM table2;Cette requête permet de lister les résultats de la table 1 sans inclure les enregistrements de la table 1 qui sont aussi dans la table 2.
Attention : Les colonnes de la première requête doivent être similaires entre la première et la deuxième requête (même nombre, même type et même ordre).
Schéma explicatif
Section titled “Schéma explicatif”Cette commande permet de récupérer les éléments de l’ensemble A sans prendre en compte les éléments de A qui sont aussi présents dans l’ensemble B. Dans le schéma ci-dessous, seule la zone de gauche (A seul) sera retournée grâce à la commande EXCEPT (ou MINUS).
┌─────────────────────────────────────┐│ EXCEPT / MINUS ││ ┌──────────┐ ┌──────────┐ ││ │ A │ │ B │ ││ │ ┌────┐ │ │ ┌────┐ │ ││ │ │ A │ │ │ │ A∩B│ │ ││ │ │seul│ │ │ │ │ │ ││ │ └────┘ │ │ └────┘ │ ││ └──────────┘ └──────────┘ ││ A sans les éléments de B ││ (A \ B = uniquement A seul) │└─────────────────────────────────────┘Exemple concret
Section titled “Exemple concret”Imaginons un système informatique d’une entreprise. Ce système contient 2 tables :
- Une table
clients_inscritsqui contient les prénoms, noms et date d’inscription des clients. - Une table
clients_refus_emailqui contient les informations des clients qui ne souhaitent pas être contactés par email.
Cet exemple aura pour objectif de sélectionner les utilisateurs pour envoyer un email d’information. Les utilisateurs de la deuxième table ne devront pas apparaître dans les résultats.
Table clients_inscrits
Section titled “Table clients_inscrits”| id | prenom | nom | date_inscription |
|---|---|---|---|
| 1 | Lionel | Martineau | 2012-11-14 |
| 2 | Paul | Cornu | 2012-12-15 |
| 3 | Sarah | Schmitt | 2012-12-17 |
| 4 | Sabine | Lenoir | 2012-12-18 |
Table clients_refus_email
Section titled “Table clients_refus_email”| id | prenom | nom | date_inscription |
|---|---|---|---|
| 1 | Paul | Cornu | 2013-01-27 |
| 2 | Manuel | Guillot | 2013-01-27 |
| 3 | Sabine | Lenoir | 2013-01-29 |
| 4 | Natalie | Petitjean | 2013-02-03 |
Pour pouvoir sélectionner uniquement le prénom et le nom des utilisateurs qui acceptent de recevoir des emails informatifs, la requête SQL à utiliser est la suivante :
SELECT prenom, nom FROM clients_inscritsEXCEPTSELECT prenom, nom FROM clients_refus_email;Résultat
Section titled “Résultat”| prenom | nom |
|---|---|
| Lionel | Martineau |
| Sarah | Schmitt |
Ce tableau de résultats montre bien les utilisateurs qui sont inscrits et qui ne sont pas présents dans le deuxième tableau. Par ailleurs, les résultats du deuxième tableau ne sont pas présents sur ce résultat final.
Compatibilité selon les SGBD
Section titled “Compatibilité selon les SGBD”| SGBD | Commande supportée |
|---|---|
| PostgreSQL | EXCEPT |
| SQL Server | EXCEPT |
| Oracle | MINUS |
| MySQL 8.0.31+ | EXCEPT (et MINUS pour compatibilité) |
| MySQL < 8.0.31 | Non supporté (utiliser une sous-requête) |
| SQLite 3.8.3+ | EXCEPT |
Alternative pour MySQL (versions antérieures) :
Section titled “Alternative pour MySQL (versions antérieures) :”SELECT DISTINCT prenom, nom FROM clients_inscritsWHERE (prenom, nom) NOT IN ( SELECT prenom, nom FROM clients_refus_email);Ou avec une sous-requête NOT EXISTS :
SELECT DISTINCT prenom, nom FROM clients_inscrits ciWHERE NOT EXISTS ( SELECT * FROM clients_refus_email cre WHERE cre.prenom = ci.prenom AND cre.nom = ci.nom);Règles importantes
Section titled “Règles importantes”1. Même nombre de colonnes
Section titled “1. Même nombre de colonnes”Les requêtes doivent retourner le même nombre de colonnes :
-- ✅ ValideSELECT id, nom FROM table1EXCEPTSELECT id, nom FROM table2;
-- ❌ Invalide (nombre de colonnes différent)SELECT id, nom, prenom FROM table1EXCEPTSELECT id, nom FROM table2;2. Types de données compatibles
Section titled “2. Types de données compatibles”Les colonnes correspondantes doivent avoir des types de données compatibles.
3. Ordre des colonnes
Section titled “3. Ordre des colonnes”L’ordre des colonnes doit être le même.
EXCEPT ALL (extension)
Section titled “EXCEPT ALL (extension)”Certains SGBD (comme PostgreSQL) proposent EXCEPT ALL qui conserve les doublons. Par défaut, EXCEPT supprime les doublons comme UNION ou INTERSECT.
-- PostgreSQL uniquementSELECT * FROM table1EXCEPT ALLSELECT * FROM table2;Comparaison des opérateurs ensemblistes
Section titled “Comparaison des opérateurs ensemblistes”| Opérateur | Résultat |
|---|---|
| UNION | A ∪ B (sans doublons) |
| UNION ALL | A ∪ B (avec doublons) |
| INTERSECT | A ∩ B (éléments communs) |
| EXCEPT | A \ B (éléments de A qui ne sont pas dans B) |
Prochain chapitre
Section titled “Prochain chapitre”Vous savez désormais comment soustraire des résultats avec EXCEPT / MINUS. Il est temps de passer à la manipulation des données, en commençant par l’ajout de nouvelles lignes dans une table.
👉 Chapitre 20 : INSERT INTO – Ajouter des lignes
Bonne continuation !
Junior TSAFACK – 08/08/2026