Requêtes SQL d’extraction : sélection, projection et jointures
Écrire des requêtes SQL-92 avec SELECT, FROM, WHERE, INNER JOIN, LEFT JOIN et RIGHT JOIN pour répondre à des besoins d’information.
Objectifs de la leçon
Dans cette leçon, l’objectif est d’apprendre à extraire des informations d’une base de données en écrivant des requêtes SQL-92 adaptées à un besoin d’information. Plus précisément, vous allez apprendre à :
- manipuler des données d’une base de données par l’interrogation ;
- écrire des requêtes d’extraction de données en réponse à une question de gestion ;
- utiliser les clauses fondamentales SELECT, FROM et WHERE ;
- comprendre la logique de la projection et de la sélection ;
- relier plusieurs tables avec INNER JOIN, LEFT JOIN et RIGHT JOIN ;
- transformer un besoin métier en requête exploitable.
Cette leçon s’inscrit dans la partie La gestion des données du système d’information et prolonge les leçons précédentes sur le modèle relationnel, les clés primaires et les clés étrangères. Ici, on ne conçoit plus seulement la structure de la base : on apprend à lire les données utiles.
1. Pourquoi utiliser des requêtes SQL d’extraction ?
Dans une organisation, les données sont stockées dans plusieurs tables : clients, factures, produits, commandes, salariés, écritures comptables, etc. Mais ces données brutes n’ont de valeur que si l’on peut répondre à des questions concrètes, par exemple :
- quels sont les clients situés à Lyon ?
- quelles commandes ont été passées en mars ?
- quels produits n’ont jamais été vendus ?
- quelles factures sont liées à quel client ?
Le langage SQL permet précisément cela : interroger une base de données pour en extraire les informations pertinentes.
Il faut bien distinguer deux idées :
- stocker les données : rôle de la base de données ;
- extraire les données utiles : rôle de la requête SQL.
Une bonne requête répond à un besoin d’information de manière :
- exacte ;
- lisible ;
- fiable ;
- reproductible.
En contexte de gestion, cela permet d’alimenter :
- des tableaux de suivi ;
- des contrôles internes ;
- des états de gestion ;
- des analyses commerciales ou administratives.
2. Rappel : table, ligne, colonne et relation
Avant d’écrire une requête, il faut raisonner correctement sur la structure de la base.
Une base relationnelle est composée de tables.
Chaque table contient :
- des colonnes : les attributs ;
- des lignes : les enregistrements.
Exemple de structure
Table Client
| IdClient | NomClient | Ville | CodePostal | |---|---|---|---| | 1 | Durand SA | Lyon | 69003 | | 2 | Martin SARL | Paris | 75012 | | 3 | Alpes Distribution | Grenoble | 38000 |
Table Commande
| IdCommande | DateCommande | Montant | IdClient | |---|---|---:|---:| | 101 | 2025-03-02 | 1250 | 1 | | 102 | 2025-03-05 | 980 | 2 | | 103 | 2025-03-10 | 430 | 1 |
Ici :
IdClientest la clé primaire deClient;IdClientdansCommandeest une clé étrangère ;- cette clé étrangère permet de relier une commande à un client.
C’est cette relation qui rend possible l’usage des jointures.
3. La logique d’une requête d’extraction
Une requête SQL d’extraction répond en général à trois questions :
- Quelles colonnes veut-on afficher ? →
SELECT - Dans quelle(s) table(s) chercher ? →
FROM - Quelles lignes garder ? →
WHERE
Quand plusieurs tables sont nécessaires, on ajoute une quatrième question :
- Comment relier les tables ? →
JOIN ... ON
La structure générale est donc :
SELECT colonnes
FROM table
WHERE condition;
ou, avec jointure :
SELECT colonnes
FROM table1
INNER JOIN table2 ON condition_de_jointure
WHERE condition;
4. La projection : choisir les colonnes avec SELECT
La projection consiste à choisir les colonnes que l’on souhaite voir apparaître dans le résultat.
4.1. Sélectionner toutes les colonnes
SELECT *
FROM Client;
Cette requête affiche toutes les colonnes de la table Client.
Pourquoi éviter SELECT * dans beaucoup de cas ?
Même si cette écriture est pratique, elle est souvent peu pertinente en contexte professionnel, car :
- elle retourne parfois trop d’informations ;
- elle rend la requête moins lisible ;
- elle peut ralentir l’extraction si la table contient beaucoup de colonnes.
Il est donc préférable de sélectionner seulement les colonnes utiles.
4.2. Sélectionner certaines colonnes
SELECT NomClient, Ville
FROM Client;
Résultat attendu : uniquement le nom du client et sa ville.
4.3. Renommer une colonne affichée
Pour rendre le résultat plus lisible, on peut utiliser un alias avec AS.
SELECT NomClient AS Client, Ville AS Commune
FROM Client;
L’alias ne modifie pas la structure de la base. Il modifie seulement l’intitulé affiché dans le résultat.
4.4. Projection et besoin métier
Exemple de besoin :
« Je veux la liste des clients et de leur ville. »
Traduction SQL :
SELECT NomClient, Ville
FROM Client;
Le travail essentiel consiste à repérer les informations utiles, ni plus ni moins.
5. La sélection : filtrer les lignes avec WHERE
La sélection consiste à ne conserver que les lignes qui respectent une condition.
5.1. Condition simple d’égalité
SELECT NomClient, Ville
FROM Client
WHERE Ville = 'Lyon';
Cette requête retourne uniquement les clients situés à Lyon.
5.2. Conditions sur les nombres
SELECT IdCommande, DateCommande, Montant
FROM Commande
WHERE Montant > 1000;
Ici, on extrait les commandes dont le montant est supérieur à 1 000.
5.3. Conditions sur les dates
SELECT IdCommande, DateCommande
FROM Commande
WHERE DateCommande = '2025-03-05';
5.4. Conditions multiples avec AND
SELECT NomClient, Ville
FROM Client
WHERE Ville = 'Lyon' AND CodePostal = '69003';
Les deux conditions doivent être vraies.
5.5. Conditions alternatives avec OR
SELECT NomClient, Ville
FROM Client
WHERE Ville = 'Lyon' OR Ville = 'Grenoble';
Au moins une des conditions doit être vraie.
5.6. Exclure avec NOT
SELECT NomClient, Ville
FROM Client
WHERE NOT Ville = 'Paris';
5.7. Utiliser des parenthèses
Quand une condition devient complexe, les parenthèses sont essentielles.
SELECT NomClient, Ville
FROM Client
WHERE (Ville = 'Lyon' OR Ville = 'Grenoble')
AND CodePostal <> '69003';
Elles évitent les ambiguïtés de lecture.
6. Lire une requête dans le bon ordre logique
Même si l’on écrit :
SELECTFROMWHERE
on raisonne souvent ainsi :
- Je pars de quelle table ?
- Quelles lignes m’intéressent ?
- Quelles colonnes dois-je afficher ?
Exemple :
« Je veux les noms des clients situés à Paris. »
Raisonnement :
- table utilisée :
Client - filtre :
Ville = 'Paris' - colonnes à afficher :
NomClient
Requête :
SELECT NomClient
FROM Client
WHERE Ville = 'Paris';
Cette méthode évite beaucoup d’erreurs.
7. Les jointures : pourquoi sont-elles indispensables ?
Dans une base relationnelle, les informations sont réparties entre plusieurs tables pour éviter les redondances.
Par exemple :
- les clients sont dans
Client; - les commandes sont dans
Commande.
Si l’on veut obtenir :
« le numéro de commande, sa date et le nom du client »
une seule table ne suffit pas.
Il faut relier les tables.
C’est le rôle des jointures.
Une jointure repose sur une relation logique, souvent :
- clé primaire d’une table ;
- clé étrangère d’une autre table.
Ici :
Client.IdClientCommande.IdClient
8. INNER JOIN : ne garder que les correspondances
8.1. Principe
INNER JOIN retourne uniquement les lignes pour lesquelles il existe une correspondance dans les deux tables.
8.2. Syntaxe
SELECT colonnes
FROM table1
INNER JOIN table2 ON condition_de_jointure;
8.3. Exemple simple
SELECT Commande.IdCommande, Commande.DateCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
Explication
- on part de la table
Commande; - on la relie à
Clientgrâce àIdClient; - on affiche le numéro de commande, la date et le nom du client.
Pourquoi cela fonctionne ?
Parce que chaque commande contient l’identifiant du client auquel elle se rattache.
8.4. Résultat attendu
| IdCommande | DateCommande | NomClient | |---|---|---| | 101 | 2025-03-02 | Durand SA | | 102 | 2025-03-05 | Martin SARL | | 103 | 2025-03-10 | Durand SA |
8.5. Cas d’usage typique
- rattacher une facture à un client ;
- rattacher une ligne de commande à un produit ;
- rattacher une écriture à un compte ;
- rattacher un salarié à un service.
9. LEFT JOIN : conserver toutes les lignes de gauche
9.1. Principe
LEFT JOIN retourne :
- toutes les lignes de la table placée à gauche ;
- et, quand c’est possible, les lignes correspondantes de la table de droite.
S’il n’existe pas de correspondance, les colonnes de droite prennent une valeur nulle (NULL).
9.2. Pourquoi utiliser LEFT JOIN ?
Parce qu’on veut souvent repérer les éléments avec ou sans correspondance.
Exemple de besoin :
« Je veux la liste de tous les clients, y compris ceux qui n’ont passé aucune commande. »
9.3. Requête
SELECT Client.NomClient, Commande.IdCommande, Commande.DateCommande
FROM Client
LEFT JOIN Commande ON Client.IdClient = Commande.IdClient;
9.4. Interprétation
- tous les clients apparaissent ;
- si un client n’a pas de commande, les colonnes de
CommandevalentNULL.
9.5. Exemple de résultat
| NomClient | IdCommande | DateCommande | |---|---|---| | Durand SA | 101 | 2025-03-02 | | Durand SA | 103 | 2025-03-10 | | Martin SARL | 102 | 2025-03-05 | | Alpes Distribution | NULL | NULL |
On voit ainsi qu’Alpes Distribution n’a passé aucune commande.
9.6. Cas d’usage typiques
- clients sans commande ;
- produits jamais vendus ;
- salariés sans affectation ;
- fournisseurs sans facture enregistrée.
10. RIGHT JOIN : conserver toutes les lignes de droite
10.1. Principe
RIGHT JOIN est symétrique de LEFT JOIN.
Il retourne :
- toutes les lignes de la table placée à droite ;
- et les correspondances éventuelles de la table de gauche.
10.2. Exemple
SELECT Client.NomClient, Commande.IdCommande
FROM Client
RIGHT JOIN Commande ON Client.IdClient = Commande.IdClient;
Ici, toutes les commandes apparaissent, même si un problème de correspondance existe côté client.
10.3. Remarque pratique
Dans beaucoup de situations, on préfère réécrire la requête avec LEFT JOIN, car c’est souvent plus intuitif : on place à gauche la table que l’on veut conserver entièrement.
Ainsi, la requête précédente pourrait souvent être pensée plus simplement comme :
SELECT Client.NomClient, Commande.IdCommande
FROM Commande
LEFT JOIN Client ON Commande.IdClient = Client.IdClient;
Le résultat logique est équivalent sur le principe de conservation des lignes.
11. Bien écrire les jointures : méthode pas à pas
Quand plusieurs tables interviennent, il faut éviter d’écrire au hasard. Voici une méthode fiable.
Étape 1 : formuler le besoin
Exemple :
« Afficher le numéro de commande, la date et le nom du client. »
Étape 2 : repérer les tables utiles
CommandeClient
Étape 3 : repérer le lien entre les tables
Commande.IdClient = Client.IdClient
Étape 4 : choisir le type de jointure
- si l’on veut seulement les commandes ayant un client :
INNER JOIN - si l’on veut tous les clients, même sans commande :
LEFT JOIN
Étape 5 : choisir les colonnes affichées
Commande.IdCommandeCommande.DateCommandeClient.NomClient
Étape 6 : écrire la requête
SELECT Commande.IdCommande, Commande.DateCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
12. L’importance de qualifier les colonnes
Quand plusieurs tables possèdent des colonnes de même nom, il faut préciser à quelle table appartient chaque colonne.
Exemple :
Client.IdClientCommande.IdClient
Si l’on écrit seulement IdClient, le système peut ne pas savoir laquelle utiliser.
Il faut donc écrire :
SELECT Commande.IdCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
Cette qualification améliore aussi la lisibilité, même quand il n’y a pas d’ambiguïté.
13. Utiliser des alias de table pour alléger l’écriture
Quand les noms de tables sont longs, on peut utiliser des alias.
Exemple
SELECT c.IdCommande, c.DateCommande, cl.NomClient
FROM Commande c
INNER JOIN Client cl ON c.IdClient = cl.IdClient;
Ici :
cest l’alias deCommande;clest l’alias deClient.
Pourquoi utiliser des alias ?
- la requête devient plus courte ;
- elle est plus lisible dans les jointures multiples ;
- elle reste claire si les alias sont bien choisis.
Attention : les alias ne doivent pas nuire à la compréhension.
14. Combiner jointure et filtre WHERE
Une requête complète combine souvent :
- projection (
SELECT) ; - source (
FROM) ; - relation (
JOIN) ; - filtre (
WHERE).
Exemple
« Afficher les commandes de clients situés à Lyon. »
SELECT Commande.IdCommande, Commande.DateCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient
WHERE Client.Ville = 'Lyon';
Raisonnement
- on relie commandes et clients ;
- on filtre sur la ville du client ;
- on affiche les informations utiles.
15. Exemples progressifs de besoins d’information
15.1. Exemple 1 : liste simple
« Donner les noms des clients. »
SELECT NomClient
FROM Client;
Notion mobilisée
- projection simple.
15.2. Exemple 2 : filtre simple
« Donner les noms des clients de Paris. »
SELECT NomClient
FROM Client
WHERE Ville = 'Paris';
Notions mobilisées
- projection ;
- sélection.
15.3. Exemple 3 : extraction de commandes élevées
« Donner les commandes supérieures à 1 000 €. »
SELECT IdCommande, DateCommande, Montant
FROM Commande
WHERE Montant > 1000;
Notions mobilisées
- filtre sur une valeur numérique.
15.4. Exemple 4 : jointure interne
« Donner le numéro de commande et le nom du client. »
SELECT Commande.IdCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
Notions mobilisées
- jointure interne.
15.5. Exemple 5 : clients sans commande
« Donner tous les clients, même ceux qui n’ont passé aucune commande. »
SELECT Client.NomClient, Commande.IdCommande
FROM Client
LEFT JOIN Commande ON Client.IdClient = Commande.IdClient;
Notions mobilisées
- jointure externe gauche.
16. Cas pratique guidé
On considère les tables suivantes.
Table Produit
| IdProduit | LibelleProduit | PrixUnitaire | |---|---|---:| | 10 | Clavier | 35 | | 11 | Souris | 18 | | 12 | Écran | 160 |
Table LigneCommande
| IdCommande | IdProduit | Quantite | |---|---|---:| | 101 | 10 | 2 | | 101 | 11 | 1 | | 102 | 12 | 3 |
Besoin 1
« Afficher les produits avec leur prix unitaire. »
SELECT LibelleProduit, PrixUnitaire
FROM Produit;
Besoin 2
« Afficher les produits dont le prix est supérieur à 20 €. »
SELECT LibelleProduit, PrixUnitaire
FROM Produit
WHERE PrixUnitaire > 20;
Besoin 3
« Afficher les lignes de commande avec le libellé du produit. »
SELECT LigneCommande.IdCommande, Produit.LibelleProduit, LigneCommande.Quantite
FROM LigneCommande
INNER JOIN Produit ON LigneCommande.IdProduit = Produit.IdProduit;
Pourquoi cette requête est correcte ?
Parce que :
LigneCommandecontient l’identifiant du produit ;Produitcontient le libellé ;- la jointure permet de remplacer un identifiant technique par une information lisible.
C’est un usage extrêmement fréquent en gestion.
17. Erreurs fréquentes à éviter
17.1. Oublier la condition de jointure
Écriture incorrecte :
SELECT *
FROM Commande
INNER JOIN Client;
Problème : une jointure doit préciser comment les tables sont reliées.
Correction :
SELECT *
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
17.2. Relier les mauvaises colonnes
Écriture incorrecte :
SELECT *
FROM Commande
INNER JOIN Client ON Commande.IdCommande = Client.IdClient;
Problème : les colonnes comparées n’ont pas le même sens.
Une jointure doit relier des colonnes correspondant à la relation logique du modèle.
17.3. Confondre filtre et jointure
La condition de jointure relie les tables ; la clause WHERE filtre le résultat.
Exemple correct :
SELECT Commande.IdCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient
WHERE Client.Ville = 'Lyon';
ON: explique le lien entre tables ;WHERE: sélectionne les lignes utiles.
17.4. Afficher trop de colonnes
Une requête doit répondre à une question précise. Afficher toutes les colonnes nuit souvent à la lisibilité.
Mieux vaut écrire :
SELECT NomClient, Ville
FROM Client;
plutôt que :
SELECT *
FROM Client;
si le besoin porte seulement sur le nom et la ville.
17.5. Oublier les guillemets sur les chaînes de caractères
WHERE Ville = Lyon
est incorrect.
Il faut écrire :
WHERE Ville = 'Lyon'
18. Méthode générale pour répondre à un besoin d’information
Voici une méthode simple, très utile en DCG.
1. Lire la demande avec précision
Exemple :
« Afficher les noms des clients et les numéros de leurs commandes, uniquement pour les clients de Paris. »
2. Repérer les informations à afficher
- nom du client ;
- numéro de commande.
3. Repérer les tables concernées
ClientCommande
4. Repérer le lien entre les tables
Client.IdClient = Commande.IdClient
5. Repérer le filtre
Ville = 'Paris'
6. Choisir la jointure adaptée
- ici, si l’on veut seulement les clients ayant des commandes :
INNER JOIN
7. Écrire la requête
SELECT Client.NomClient, Commande.IdCommande
FROM Client
INNER JOIN Commande ON Client.IdClient = Commande.IdClient
WHERE Client.Ville = 'Paris';
19. Exercices d’application corrigés
Exercice 1
On dispose d’une table Fournisseur :
| IdFournisseur | NomFournisseur | Ville | |---|---|---| | 1 | Alpha | Lille | | 2 | Beta | Nantes | | 3 | Gamma | Lille |
Question
Afficher le nom des fournisseurs situés à Lille.
Correction
SELECT NomFournisseur
FROM Fournisseur
WHERE Ville = 'Lille';
Explication
SELECT: colonne affichée ;FROM: table utilisée ;WHERE: filtre sur la ville.
Exercice 2
On dispose des tables Client et Commande.
Question
Afficher la date de commande et le nom du client.
Correction
SELECT Commande.DateCommande, Client.NomClient
FROM Commande
INNER JOIN Client ON Commande.IdClient = Client.IdClient;
Explication
La date est dans Commande, le nom dans Client. Une jointure est donc nécessaire.
Exercice 3
Question
Afficher tous les clients, y compris ceux n’ayant passé aucune commande.
Correction
SELECT Client.NomClient, Commande.IdCommande
FROM Client
LEFT JOIN Commande ON Client.IdClient = Commande.IdClient;
Explication
On veut conserver tous les clients : la table Client doit donc être à gauche dans un LEFT JOIN.
Exercice 4
On dispose des tables Produit et LigneCommande.
Question
Afficher le libellé du produit et la quantité commandée.
Correction
SELECT Produit.LibelleProduit, LigneCommande.Quantite
FROM LigneCommande
INNER JOIN Produit ON LigneCommande.IdProduit = Produit.IdProduit;
Explication
Le besoin impose de croiser deux tables : l’une contient la quantité, l’autre le libellé.
20. Cas de synthèse
On considère les tables suivantes :
Client(IdClient, NomClient, Ville)Commande(IdCommande, DateCommande, IdClient)LigneCommande(IdCommande, IdProduit, Quantite)Produit(IdProduit, LibelleProduit, PrixUnitaire)
Objectif
« Afficher pour chaque ligne de commande le numéro de commande, le nom du client, le libellé du produit et la quantité. »
Analyse
Informations à afficher :
Commande.IdCommandeClient.NomClientProduit.LibelleProduitLigneCommande.Quantite
Tables nécessaires :
CommandeClientLigneCommandeProduit
Liens :
Commande.IdClient = Client.IdClientLigneCommande.IdCommande = Commande.IdCommandeLigneCommande.IdProduit = Produit.IdProduit
Requête
SELECT Commande.IdCommande,
Client.NomClient,
Produit.LibelleProduit,
LigneCommande.Quantite
FROM LigneCommande
INNER JOIN Commande ON LigneCommande.IdCommande = Commande.IdCommande
INNER JOIN Client ON Commande.IdClient = Client.IdClient
INNER JOIN Produit ON LigneCommande.IdProduit = Produit.IdProduit;
Ce que montre cet exemple
Une requête d’extraction peut mobiliser plusieurs jointures successives pour reconstruire une information complète à partir d’un modèle relationnel normalisé.
C’est précisément l’intérêt du SQL dans la gestion des données du système d’information.
21. Conseils de rédaction d’une requête SQL
Pour produire une requête claire et professionnelle :
- placer chaque clause sur une ligne distincte ;
- indenter les jointures ;
- qualifier les colonnes avec le nom de la table ou un alias ;
- ne sélectionner que les colonnes utiles ;
- vérifier la cohérence entre le besoin et le type de jointure.
Exemple bien présenté
SELECT c.IdCommande,
c.DateCommande,
cl.NomClient
FROM Commande c
INNER JOIN Client cl ON c.IdClient = cl.IdClient
WHERE cl.Ville = 'Lyon';
Cette présentation facilite :
- la lecture ;
- la vérification ;
- la maintenance.
22. Ce qu’il faut retenir sur SELECT, FROM, WHERE et JOIN
SELECT
Permet la projection : choisir les colonnes affichées.
FROM
Indique la ou les tables sources.
WHERE
Permet la sélection : filtrer les lignes selon une condition.
INNER JOIN
Conserve seulement les lignes ayant une correspondance dans les deux tables.
LEFT JOIN
Conserve toutes les lignes de la table de gauche, avec correspondance éventuelle à droite.
RIGHT JOIN
Conserve toutes les lignes de la table de droite, avec correspondance éventuelle à gauche.
23. Mémo final
Démarche type
- Identifier le besoin d’information.
- Repérer les colonnes à afficher.
- Repérer les tables concernées.
- Identifier les relations entre tables.
- Choisir le bon type de jointure.
- Ajouter les filtres nécessaires.
- Vérifier que le résultat attendu correspond bien à la demande.
Formes essentielles à connaître
SELECT colonne1, colonne2
FROM Table;
SELECT colonne1, colonne2
FROM Table
WHERE condition;
SELECT t1.colonne, t2.colonne
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.cle = t2.cle;
SELECT t1.colonne, t2.colonne
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.cle = t2.cle;
SELECT t1.colonne, t2.colonne
FROM Table1 t1
RIGHT JOIN Table2 t2 ON t1.cle = t2.cle;
Idée centrale
Écrire une requête SQL d’extraction, ce n’est pas seulement connaître une syntaxe. C’est surtout savoir traduire un besoin de gestion en logique relationnelle, afin d’extraire des informations d’une base de données de façon fiable et pertinente.
Résumé
Dans cette leçon, vous avez vu comment manipuler des données d’une base de données par des requêtes d’extraction SQL-92. Vous savez désormais :
- utiliser SELECT pour la projection ;
- utiliser WHERE pour la sélection ;
- utiliser INNER JOIN, LEFT JOIN et RIGHT JOIN pour relier des tables ;
- construire une requête à partir d’un besoin d’information ;
- éviter les erreurs les plus fréquentes.
Cette compétence est fondamentale dans la gestion des données du système d’information, car elle permet de passer de données stockées à une information utile pour la gestion.