Soustraction SQL expliquée avec exemples simples

La soustraction SQL tient une place cruciale dans la gestion des bases de données relationnelles. On l'utilise pour extraire des données présentes dans une table mais absentes dans une autre. C'est un vrai coup de pouce pour les analyses comparatives ou le nettoyage des données. Même si ce concept peut paraître abstrait pour les novices, il repose sur une idée simple : sélectionner un sous-ensemble distinct à partir d'un ensemble initial.
Saisir enfin la notion de soustraction en SQL, sans prise de tête
Avant de se jeter à corps perdu dans la syntaxe, il faut d'abord bien réaliser que la soustraction en SQL n'est pas juste une banale opération arithmétique. C'est une manière élégante de dénicher la différence entre deux ensembles de données. En SQL, on a souvent recours aux opérateurs MINUS ou EXCEPT selon le système de gestion de base de données utilisé pour trouver les enregistrements présents dans un ensemble mais absents de l'autre.
- Extraire les enregistrements qui figurent dans une table mais manquent dans une autre, un peu comme dénicher ce qui est absent du tableau d'ensemble.
- Elle ne faut pas la confondre avec la soustraction arithmétique qui calcule la différence numérique entre deux valeurs.
- Nettoyer les données, comparer des listes ou simplement examiner les petits écarts entre deux jeux de résultats, c'est un vrai coup de pouce dans ces cas-là.
- Cette soustraction fait partie des opérations dites ensemblistes, avec les opérateurs UNION et INTERSECT. C'est une petite équipe qui fait le boulot en coulisses.
Comprendre la syntaxe de la soustraction en SQL, sans prise de tête
La façon dont on écrit une soustraction en SQL dépend surtout du système de gestion de base de données utilisé. C'est un vrai casse-tête pour les non-initiés. Chez Oracle, on a l'opérateur MINUS
. PostgreSQL, SQL Server et consorts préfèrent largement EXCEPT
. Grosso modo, ces deux opérateurs jouent à peu près le même jeu. Ils vous renvoient les lignes présentes dans la première requête mais absentes dans la seconde. Attention, pour que tout roule, il faut que les colonnes sélectionnées dans les deux requêtes soient du même type et dans le même ordre.
SGBD | Opérateur | Exemple de requête | Colonnes requises | Particularités |
---|---|---|---|---|
Oracle | MINUS | SELECT col1 FROM TableA MINUS SELECT col1 FROM TableB | Les colonnes doivent être strictement du même type et en nombre identique, pas de place pour l’improvisation | Opérateur bien à lui, propre à Oracle, et franchement simple à prendre en main |
PostgreSQL | EXCEPT | SELECT col1 FROM TableA EXCEPT SELECT col1 FROM TableB | Colonnes compatibles en type et en nombre, un classique fiable | Plus expressif et supporté par plusieurs SGBD, ce qui ne gâche rien |
SQL Server | EXCEPT | SELECT col1 FROM TableA EXCEPT SELECT col1 FROM TableB | Correspondance parfaite entre colonnes exigée, sans compromis | Supporte aussi EXCEPT, souvent préféré à MINUS, ce qui le rend plutôt populaire |
MySQL | N/A | Utilisables via JOIN ou NOT EXISTS (pas d'opérateur dédié) | Gestion manuelle nécessaire avec des jointures, un peu de réglage au cas par cas | Ne propose pas MINUS ou EXCEPT en natif, il faut donc se retrousser les manches et choisir une alternative |
Quelques exemples simples pour apprendre la soustraction en SQL, pas à pas, sans se prendre la tête
Voyons un premier exemple concret qui a pour but de retirer de la table A les éléments présents aussi dans la table B afin de ne garder que ceux qui lui sont bien propres, rien de superflu.
[code-block attributes={"content":"SELECT colonne1 FROM tableA\nMINUS\nSELECT colonne1 FROM tableB;"} end]
Cette requête récupère toutes les valeurs de colonne1 présentes dans tableA mais qui n’ont pas encore été enregistrées dans tableB. Cela est particulièrement utile pour isoler les commandes non traitées, celles qui apparaissent dans la liste générale (tableA) mais qui n’ont pas encore été enregistrées comme envoyées (tableB).
Prenons un second exemple avec PostgreSQL où l'on souhaite comparer deux listes de clients un peu plus corsées comportant plusieurs colonnes. Ici on fait appel à l’opérateur EXCEPT
pour dénicher les clients qui se trouvent dans la première liste mais pas dans la deuxième.
[code-block attributes={"content":"SELECT nom, prenom FROM Clients1\nEXCEPT\nSELECT nom, prenom FROM Clients2;"} end]
La requête commence par récupérer les noms et prénoms de la table Clients1 avant de retirer ceux qui apparaissent aussi dans Clients2. Pour que cette comparaison fonctionne bien, il faut absolument que les deux sélections ciblent les mêmes colonnes dans le même ordre avec des types compatibles.
Exemples concrets qui montrent vraiment à quoi sert la soustraction en SQL
- Repérer les enregistrements uniques qui apparaissent dans une table mais pas dans une autre.
- Nettoyer une base de données en supprimant les doublons présents dans une autre table de référence.
- Comparer des listes d’utilisateurs, de produits ou de transactions pour dénicher les différences ou les oublis.
- Étudier les changements entre deux instantanés de données réalisés à des moments différents.
- Filtrer les éléments absents d’une liste de référence.
Une entreprise peut vouloir isoler les nouveaux clients qui ont passé commande ce mois-ci alors qu'ils ne figuraient pas dans sa base historique. Ou encore, lorsqu'elle reçoit un fichier de données externes, la soustraction lui sert à ôter les références déjà présentes pour éviter les fameux doublons qui nous jouent parfois des tours.
Limites et points d'attention à garder en tête avec la soustraction SQL
Il faut vraiment garder à l'esprit quelques petites contraintes quand on veut jouer avec la soustraction SQL sans se prendre les pieds dans le tapis. Les colonnes concernées doivent correspondre pile-poil tant en nombre qu'en type sinon la requête ne passera pas. Selon le SGBD utilisé, MINUS et EXCEPT ne sont pas toujours copains sur tous les fronts. Cela peut rendre la portabilité un peu capricieuse, on va dire. D'ailleurs, quand aucune différence ne pointe le bout de son nez, la requête vous renvoie un résultat tout vide, un détail à ne pas balayer d’un revers de main.
- Les colonnes doivent correspondre à la perfection que ce soit en nombre, en ordre ou en type entre les deux sélections. Pas de place pour l'à-peu-près ici.
- MINUS est la spécialité de certains SGBD comme Oracle tandis que EXCEPT, plus courant, fait le boulot même s'il peut parfois ramer un peu.
- Une requête sans différence renvoie un ensemble vide, ce qui peut surprendre si on ne fait pas attention au contexte d'utilisation. Mieux vaut vérifier deux fois voire trois.
- Les performances ont tendance à patauger sur des tables vraiment énormes. Cela oblige souvent à sortir les index adaptés pour éviter le drame.
- Quand les contraintes se font sentir, des solutions comme NOT EXISTS ou LEFT JOIN s'invitent volontiers à la fête. Elles offrent un peu plus de souplesse et d'options.
D'autres façons de faire la soustraction SQL avec NOT EXISTS et LEFT JOIN
Les opérateurs MINUS ou EXCEPT ne sont pas proposés dans un SGBD, ou ils ne cadrent pas toujours pile poil avec les besoins précis d'une requête. Dans ces cas-là, les clauses NOT EXISTS
et les jointures LEFT JOIN
couplées à des filtres IS NULL
deviennent souvent de véritables petits coups de pouce pour obtenir un résultat qui joue le même rôle qu’une soustraction SQL.
[code-block attributes={"content":"-- Utilisation de NOT EXISTS\nSELECT colonne1 FROM tableA a\nWHERE NOT EXISTS (\n SELECT 1 FROM tableB b WHERE b.colonne1 = a.colonne1\n);"} end]
[code-block attributes={"content":"-- Utilisation de LEFT JOIN\nSELECT a.colonne1 FROM tableA a\nLEFT JOIN tableB b ON a.colonne1 = b.colonne1\nWHERE b.colonne1 IS NULL;"} end]
Ces deux méthodes permettent de réaliser des filtrages proches d'une soustraction SQL en vérifiant qu'il n'existe pas de correspondance dans la seconde table. NOT EXISTS
a l'avantage d'être plus clair et explicite, ce qui facilite la lecture du code. En revanche, LEFT JOIN
peut parfois offrir de meilleures performances selon les index en place et le système de gestion de base de données utilisé.