Requêtes SQL sur plusieurs tables : jointures, agrégation, groupement et sous-requêtes, cours, méthodes et exercices corrigés pour les ECS, ECT et ECG
Requêtes sur plusieurs tables : produit cartésien et jointures, fonctions d'agrégation, groupement (GROUP BY, HAVING), requêtes imbriquées et opérations ensemblistes, exécutées sous SQLite et depuis Python, avec des cas tirés des sujets du CNAEM, de l'ISCAE, de la BCE et d'ECRICOME.
- 22méthodes
- 55exercices corrigés
- 10problèmes
- 26pièges
- 45figures
Une jointure rapproche deux tables reliées par une clé : elle garde, parmi toutes les associations de lignes (le produit cartésien), celles où la clé étrangère est égale à la clé primaire qu'elle désigne. Elle s'écrit FROM commande INNER JOIN client ON commande.num_client = client.num_client, ou, de façon équivalente, FROM commande, client WHERE commande.num_client = client.num_client ; on ajoute une ligne INNER JOIN ... ON par table et on préfixe chaque colonne par sa table (client.nom). Les fonctions d'agrégation COUNT, SUM, AVG, MIN et MAX résument des lignes en une valeur : sans GROUP BY, elles rendent une seule ligne, et elles ignorent les valeurs NULL, sauf COUNT(*). GROUP BY calcule un agrégat pour chaque groupe (on groupe par la clé, jamais par un nom) ; HAVING filtre les groupes, alors que WHERE filtre les lignes avant le groupement. Une sous-requête est une requête entre parenthèses dans une autre : elle rend une valeur (comparée par =, <, >), une colonne (testée par IN) ou une table (lue dans FROM) ; « aucun », « jamais » s'écrivent avec NOT EXISTS. Ce chapitre d'informatique de deuxième année couvre le SQL sur plusieurs tables de l'ECS2 et de l'ECT2 au Maroc (programme fondé sur SQLite, avec GROUP BY, HAVING, les sous-requêtes, et en ECT2 NATURAL JOIN, UNION, INTERSECT, EXCEPT) et de l'ECG (mathématiques appliquées) et de l'ECT en France, où seule la jointure INNER JOIN est exigible et où les agrégats, posés aux concours, sont rappelés en annexe. Il prépare aux questions SQL du CNAEM (épreuve « Gestion, management et informatique » de la filière ECT) et des sujets de mathématiques de la BCE et d'ECRICOME. La page propose un cours avec des schémas, des méthodes avec la requête type à écrire sur la copie, des exercices corrigés dont chaque requête a été exécutée sous SQLite, et des sujets réels du CNAEM, d'ECRICOME, de la BCE et du CNC corrigés pas à pas.
Ce que tu sauras faire
Une base de données sérieuse range ses informations dans plusieurs tables reliées par des clés. Ce chapitre apprend à les interroger ensemble. À la fin, tu dois savoir :
- lire un schéma de plusieurs tables et suivre le chemin des clés entre elles ;
- reconnaître un produit cartésien et écrire une jointure (
INNER JOIN ... ON), sur deux tables ou plus ; - résumer des lignes par une fonction d'agrégation (
COUNT,SUM,AVG,MIN,MAX), sans doublon, sans somme gonflée et sans division entière ; - selon ta classe, grouper des lignes (
GROUP BY), filtrer des groupes (HAVING), poser une question dans la question (sous-requête), et combiner des résultats (UNION,INTERSECT,EXCEPT) ; - relire une requête et prévoir à la main ce qu'elle affiche.
L'essentiel : La jointure Extrait gratuit
SELECT commande.num_cde, client.nom
FROM commande
INNER JOIN client ON commande.num_client = client.num_client
WHERE commande.date_cde >= '2025-03-01';
- Même résultat :
FROM commande, client WHERE commande.num_client = client.num_client;JOINseul =INNER JOIN. - Une ligne
INNER JOIN ... ONpar table ajoutée, en suivant le chemin des clés. - Colonne présente dans deux tables : la préfixer (
client.nom), sinonambiguous column name. - Clé composée :
ON a.x = b.x AND a.y = b.y. - Une ligne sans correspondant (ou à
NULL) disparaît de la jointure.
Une méthode du chapitre Extrait gratuit
INNER JOIN ... ONLa demande affiche des colonnes de plusieurs tables, ou pose une condition dans une table pour afficher une colonne d'une autre.
FROM t1 INNER JOIN t2 ON t1.cle_etrangere = t2.cle_primaire ; une ligne INNER JOIN ... ON par table ajoutée ; WHERE, puis ORDER BY, après les jointures. Une colonne présente dans deux tables se préfixe par sa table.
- Trace le chemin des clés (méthode 1).
- Écris
FROMavec la première table, puis une ligneINNER JOIN ... ONpar table, chacune reliée à une table déjà écrite. - Écris le
SELECTavec des colonnes préfixées. - Ajoute
WHEREetORDER BY. - Relis chaque condition
ON: une clé étrangère d'un côté, la clé primaire qu'elle désigne de l'autre.
« Requête qui affiche la désignation et la quantité des produits de la commande 4 ; la jointure relie la clé étrangère ligne_commande.ref_produit à la clé primaire produit.ref_produit : »
SELECT produit.designation, ligne_commande.quantite
FROM ligne_commande
INNER JOIN produit
ON produit.ref_produit = ligne_commande.ref_produit
WHERE ligne_commande.num_cde = 4;
SQLite répond à la requête ci-dessus :
| designation | quantite |
|---|---|
| Miel d'euphorbe | 8 |
| Savon beldi | 20 |
La commande 4 contient 8 pots de miel d'euphorbe et 20 savons.
- Une colonne commune non préfixée :
ambiguous column name. - La condition sur la mauvaise colonne (
commande.num_cde = client.num_client) : des lignes fausses sans message. INNER JOINsansON: un produit cartésien.- Plusieurs tables dans un seul
ON, ou une virgule entre deuxINNER JOIN.
Exercices 2, 3, 4, 6, 7, 8, 10, 11, 14, 15, 16, 17, 20, 24, 25, 27 et 28 ; problème 3.
Un exercice corrigé Extrait gratuit
Un grossiste en épices d'Inezgane enregistre ses acheteurs et ses bons de livraison : acheteur(, nom) et bon(, date_bon, montant, #num_acheteur).
| num_acheteur | nom |
|---|---|
| 1 | Epices Souss |
| 2 | Herboristerie Atlas |
| 3 | Epicerie Fassia |
| num_bon | date_bon | montant | num_acheteur |
|---|---|---|---|
| 501 | 2025-05-02 | 1800 | 1 |
| 502 | 2025-05-04 | 950 | 2 |
| 503 | 2025-05-09 | 2400 | 1 |
| 504 | 2025-05-12 | 600 | 3 |
| 505 | 2025-05-20 | 1100 | 1 |
Écrire la requête qui donne le nombre de bons et le montant total des achats de l'acheteur « Epices Souss » en mai 2025.
- Méthode 2 : le nom de l'acheteur est dans
acheteur. - Méthode 4 :
COUNT(*)etSUM(bon.montant), sansGROUP BYpuisqu'un seul acheteur est demandé.
SELECT COUNT(*) AS nb_bons,
SUM(bon.montant) AS total
FROM bon
INNER JOIN acheteur
ON bon.num_acheteur = acheteur.num_acheteur
WHERE acheteur.nom = 'Epices Souss'
AND bon.date_bon >= '2025-05-01'
AND bon.date_bon < '2025-06-01';
SQLite répond :
| nb_bons | total |
|---|---|
| 3 | 5300 |
Vérification à la main : bons 501, 503 et 505, soit 1 800 + 2 400 + 1 100 = 5 300 DH.
Interprétation : la jointure apporte le nom ; le filtre garde les lignes de cet acheteur ; l'agrégat les résume en une ligne.
Jointure, puis filtre, puis agrégat : une seule ligne de résultat. Voir les méthodes 2 et 4.
Le cours détaillé, toute la fiche « L'essentiel », 22 méthodes, 26 pièges corrigés, la carte mentale, 55 exercices corrigés, 10 problèmes de concours, les fiches à mémoriser et l'assistant qui répond à tes questions. Ce chapitre est offert : il s’ouvre en entier avec un compte d’essai gratuit.
Ouvrir l'essai gratuitUne question ? WhatsAppPlan du cours
- 1. Pourquoi plusieurs tables
- 2. Le produit cartésien
- 3. La jointure interne
- 3.1 Joindre deux tables
- 3.2 Préfixer les colonnes
- 3.3 Les alias de table
- 3.4 Ajouter une condition, trier, retirer les doublons
- 3.5 Trois tables et plus
- 3.6 Une condition sur deux colonnes
- 3.7 Ce que la jointure perd, ce qu'elle invente
- 3.8 L'autojointure
- 3.9
NATURAL JOIN
- 4. Les fonctions d'agrégation
- 4.1 Résumer une colonne
- 4.2 Agréger après une jointure
- 4.3 Ratios et moyennes calculées
- 4.4 Une colonne à côté d'un agrégat
- 5. Écrire, relire et vérifier une requête sur plusieurs tables
- 6. Le groupement :
GROUP BY- 6.1 Un résultat pour chaque groupe
- 6.2 Grouper par la clé
- 6.3 Grouper après une jointure, trier sur un agrégat
- 6.4 Le groupe des valeurs manquantes
- 6.5 Grouper par mois ou par année
- 7. Filtrer les groupes :
HAVING- 7.1
HAVING - 7.2
WHEREouHAVING - 7.3 L'ordre complet des clauses
- 7.1
- 8. Les sous-requêtes
- 8.1 Une question dans la question
- 8.2 Une valeur : comparer
- 8.3 Une colonne :
IN - 8.4 Une table : la sous-requête dans
FROM - 8.5
EXISTS - 8.6 La négation : « aucun », « jamais »
- 8.7 La sous-requête dans
HAVING - 8.7 Sous-requêtes dans
SELECTet sous-requêtes corrélées
- 9. Les opérateurs ensemblistes
Les méthodes du chapitre
Chaque méthode est une fiche : quand l'utiliser, le rappel de cours, les étapes, la rédaction attendue sur la copie, un exemple traité, les erreurs à éviter.
- Lire un schéma et tracer le chemin des clés
- Écrire une jointure avec
INNER JOIN ... ON - Passer d'une écriture à l'autre et reconnaître un produit cartésien oublié
- Choisir et écrire un agrégat
- Calculer un ratio ou une moyenne à partir d'agrégats
- Éviter les doublons et les sommes gonflées d'une jointure
- Traduire une phrase en requête sur plusieurs tables
- Lire une requête et dire ce qu'elle affiche
- Vérifier une requête sur plusieurs tables
- Traiter une partie SQL de concours sur plusieurs tables
- Écrire un groupement avec
GROUP BY - Choisir entre
WHEREetHAVING - Écrire une sous-requête
- Trouver le ou les maximums, ex aequo compris
- Exprimer une négation : « aucun », « jamais », « pour tout »
- Écrire une autojointure ou joindre deux fois la même table
- Lire et écrire une sous-requête corrélée, ou une sous-requête dans
SELECT - Combiner des résultats avec
UNION,INTERSECT,EXCEPT - Employer
NATURAL JOINsans se tromper - Grouper par mois ou par année avec
strftime - Se servir de l'annexe de syntaxe d'un sujet
- Exécuter une jointure à la main et compter ses lignes
Les exercices corrigés
Chaque exercice a ses indications, sa correction rédigée et ce qu'il faut en retenir.
Application directe (18)
- Compter un produit cartésien et garder les lignes qui ont un sens
- Le stock du miel vendu en ligne (suite)
- Le nouveau chat d'un propriétaire (suite)
- Recensement (suite) : la catégorie de chaque individu
- Deux écritures d'une même jointure
- Préfixer : les dossiers de financement d'une banque participative
- La bonne condition de jointure : le personnel d'une coopérative
- Les ventes journalières des magasins d'une coopérative (suite)
- Les six agrégats : les dons d'une association de soutien scolaire
- Le montant total des locations de Poste Maroc en 2024
- Agrégat après jointure : le grossiste en épices
- Dire ce que fait une requête de sujet et trouver ses deux erreurs
- AVG et les cases vides : l'évaluation d'une formation
- Pour chaque ville : le premier GROUP BY
- Lire une sous-requête : un QCM de l'ISCAE
- « Jamais » n'est pas « différent » (suite)
- Au-dessous de la moyenne : les lots d'huile d'olive
- Les adhérents de deux associations : UNION, INTERSECT, EXCEPT
Entraînement (28)
- Le zoo (suite) : des doublons et une somme doublée
- Une question, deux écritures : les semences d'une coopérative
- Les ventes pour 100 000 habitants d'un magasin
- Les fournisseurs de semences d'une coopérative
- Les campagnes de sensibilisation d'une association
- Ceux que la jointure oublie
- Bons et lignes de bon : le montant d'une vente
- Corriger cinq requêtes d'une copie
- Prévoir à la main une jointure à trois tables
- Les heures et le salaire d'avril 2014 d'un agent de péage
- Jointure sur deux colonnes : comptes ouverts et population
- Les ventes d'un magasin de meubles de Salé
- Lire une jointure qui contient un OR
- Les réservations d'un hôtel
- Le coût d'une phase de projet
- Les formations du personnel d'une société d'eaux minérales
- Les ventes journalières (fin) : taux par magasin et par région
- Les fournisseurs de semences (fin) : le moins cher et les moyennes
- Les conteneurs du port de Tanger Med (suite)
- Les clients fidèles d'un grossiste en fruits
- Les points de fidélité d'une enseigne de grande distribution (suite)
- Les fournisseurs enregistrés deux fois
- L'élection du bureau d'une association (suite)
- La majorité absolue
- Le commercial qui a signé le plus de contrats d'une catégorie
- NATURAL JOIN qui trompe
- Proportion de badges par type de public d'une station de montagne
- Les dons par mois et par année
Approfondissement (9)
- Corriger la requête d'un sujet : les franchisés d'un réseau de bricolage
- Construire des lignes de test qui démasquent trois requêtes fausses
- « Tous » sans sous-requête : les notes d'un stagiaire
- Une moyenne pondérée juste : la note d'un candidat à une bourse
- Combien de lignes ? Prévoir puis vérifier
- Les négociations entre deux coopératives
- Les demandes accessibles à un sous-traitant
- « Pour tout » : les produits dont tous les essais sont conformes
- Les partenaires d'une coopérative : exécuter une requête à la main
Les problèmes de concours
Des extraits de sujets réels, corrigés en entier, avec la durée conseillée et les méthodes mobilisées.
- Les avis sur des transporteurs
- Les ordinateurs et leur durée de vie (suite)
- La maintenance des machines d'une cimenterie
- Les clients d'un fabricant d'appareillage électrique
- Les ventes d'un producteur d'huile de table par région
- La sélection des boursiers d'une fondation
- Les documents d'un serveur de fichiers (suite)
- Les forêts du monde (suite)
- Les formations des salariés d'une conserverie
- Le chiffre d'affaires d'un fabricant d'aluminium
Questions fréquentes
Comment faire une jointure entre deux tables en SQL ?
On relie la clé étrangère d'une table à la clé primaire de l'autre : SELECT commande.num_cde, client.nom FROM commande INNER JOIN client ON commande.num_client = client.num_client;. JOIN seul est un synonyme d'INNER JOIN, et la même jointure s'écrit aussi FROM commande, client WHERE commande.num_client = client.num_client. Pour une troisième table, on ajoute une ligne INNER JOIN ... ON.
Que signifie ambiguous column name en SQL ?
Une colonne de la requête porte le même nom dans deux tables jointes, et SQLite ne sait pas laquelle afficher. On la préfixe par le nom de sa table : client.num_client ou commande.num_client.
Quelle différence entre COUNT(*) et COUNT(colonne) ?
COUNT(*) compte les lignes ; COUNT(colonne) compte les valeurs non NULL de la colonne ; COUNT(DISTINCT colonne) compte ses valeurs différentes. Sur six clients dont un sans ville, COUNT(*) vaut 6 et COUNT(ville) vaut 5.
Quelle différence entre WHERE et HAVING ?
WHERE filtre les lignes avant le groupement et ne contient jamais de fonction d'agrégation (WHERE SUM(x) > 10 est refusé). HAVING filtre les groupes après GROUP BY, sur un agrégat : GROUP BY ref_produit HAVING SUM(quantite) >= 20. Ordre d'écriture : SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY.
Pourquoi une somme est-elle trop grande après une jointure ?
Si une table de la jointure a plusieurs lignes pour une même ligne qu'on somme, cette ligne est répétée avant le SUM : la somme est doublée, sans message. On calcule la somme sur la seule table qui porte les quantités, ou l'on groupe d'abord dans une sous-requête, puis on joint.
Comment trouver les clients qui n'ont jamais commandé en SQL ?
Une jointure interne ne peut pas les donner : ils en sont absents. On retire l'ensemble de ceux qui ont commandé : WHERE NOT EXISTS (SELECT * FROM commande WHERE commande.num_client = client.num_client). Avec NOT IN, un seul NULL dans la sous-requête fait rendre zéro ligne.
Le SQL sur plusieurs tables est-il au programme des ECS, ECT et ECG ?
Au Maroc, oui : jointure, agrégats, GROUP BY, HAVING et sous-requêtes sont au programme de la matière Informatique de l'ECS2 et de l'ECT2, avec SQLite ; l'ECT2 a en plus NATURAL JOIN et les opérateurs ensemblistes. En France, seule la jointure INNER JOIN ... ON avec des égalités est exigible en ECT et en ECG mathématiques appliquées ; les agrégats sont non exigibles, mais les sujets ECRICOME et BCE les posent en rappelant leur syntaxe en annexe.
Comment y accéder
Ce chapitre fait partie des chapitres offerts : il s'ouvre en entier avec un compte d'essai gratuit. Créer un compte d'essai ou se connecter. Pour l'accès complet, les tarifs ou une question, écris-nous sur WhatsApp.