Chapitre 2010 minDébutant
Méthode pour l'examen (E7 et E6)
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- repérer où le SQL tombe aux épreuves E6 et E7 ;
- lire l'énoncé et le schéma avant d'écrire ;
- appliquer une méthode en quatre temps ;
- éviter les pièges classiques et écrire du SQL lisible sur papier.
3 exercices corrigés
Les questions SQL du BTS SIO se traitent avec une méthode : lire le schéma, écrire la requête en quatre temps, puis la relire avec une checklist. Ce chapitre dit aussi où le SQL tombe, à l'écrit E7 et à l'E6 de l'option SLAM, et comment écrire une requête lisible sur papier. Les exercices utilisent la base d'exemple parc.
Où le SQL tombe
| Épreuve | Forme | Ce qu'on attend en SQL |
|---|---|---|
| E7 SLAM, Cybersécurité des services informatiques | Écrit de 4 h, étude de cas | Requêtes de consultation et d'agrégat, vues (souvent avec UNION), création de comptes et GRANT, triggers à lire, compléter ou corriger, chiffrement de colonnes, requêtes préparées dans un extrait de code |
| E6 SLAM, Conception et développement d'applications | Pratique et orale ; 1 h de réalisation autonome sur une de tes réalisations | Faire évoluer ta propre base : ajouter une table ou une colonne, écrire les requêtes du besoin exprimé par la commission, sécuriser l'accès |
| E5, Support et mise à disposition de services | Oral de 40 min sur ton parcours et ton portfolio | Pas de SQL à écrire : on te demande comment tu as sauvegardé, restauré et protégé (habilitations) les bases de tes réalisations |
| E3, Mathématiques pour l'informatique | CCF (une situation pratique et orale, une situation écrite) ou écrit ponctuel de 2 h | La théorie des ensembles, qui fonde UNION, INTERSECT et EXCEPT |
L'épreuve écrite de cybersécurité s'appelle E7 (unité U7) depuis la session 2025 ; les sujets des sessions 2022 à 2024 la nommaient E6 (U6). Ces anciens sujets restent d'excellents entraînements. En SISR, le SQL apparaît surtout autour des outils (GLPI, supervision, sauvegarde de bases) et des comptes de service.
Lire l'énoncé et le schéma
Avant d'écrire la moindre requête :
- Recopie le schéma relationnel au brouillon, en dessinant les flèches des clés étrangères. Repère les tables centrales et les associations réflexives.
- Lis les lignes de contraintes sous le schéma : une colonne
idResponsablepointe vers quelle table ? Une table d'association a-t-elle une clé composée ? - Repère les colonnes facultatives (les
NULLpossibles) : elles décident entreINNERetLEFT JOIN, et entreNOT INetNOT EXISTS. - Note le SGBD s'il est précisé (MySQL ou SQL Server dans les sujets récents). S'il ne l'est pas, écris du SQL standard :
JOIN … ON,CASE,COALESCE.
La méthode en quatre temps
Pour chaque question, avance dans cet ordre, qui est celui de l'évaluation de la requête :
- Les tables (
FROM) : celles qui contiennent les colonnes à afficher et à filtrer, plus les tables intermédiaires du chemin. - Les jointures (
JOIN … ON) : une condition par lien, en suivant les clés étrangères ;LEFT JOINsi l'énoncé dit « tous », « y compris », « même ceux qui n'ont pas ». - Les filtres (
WHERE) sur les lignes, puis les regroupements (GROUP BY) et les filtres sur les groupes (HAVING). - La présentation :
SELECT(colonnes, alias, calculs),ORDER BY,LIMIT.
Écris enfin une phrase qui relit la requête en français (« pour chaque service, je compte… ») et compare-la à la question.
Les pièges et la checklist
| Piège | Symptôme | Correction |
|---|---|---|
= NULL | Aucune ligne | IS NULL |
NOT IN sur une colonne qui contient des NULL | Aucune ligne | NOT EXISTS, ou IS NOT NULL dans la sous-requête |
Colonne hors GROUP BY et hors agrégat | Erreur 1055, ou valeur arbitraire | Ajouter la colonne au GROUP BY ou l'agréger |
Condition sur un agrégat dans WHERE | Erreur 1111 | La mettre dans HAVING |
Condition sur la table de droite d'un LEFT JOIN dans WHERE | Les lignes sans correspondance disparaissent | Déplacer la condition dans le ON |
COUNT(*) après un LEFT JOIN | 1 au lieu de 0 | COUNT(colonne_de_droite) |
| Condition de jointure oubliée | Produit cartésien, résultat énorme | Une condition par jointure |
AND et OR mélangés sans parenthèses | Lignes en trop | Parenthèses |
BETWEEN sur un DATETIME | Le dernier jour est exclu | >= début AND < lendemain de la fin |
UPDATE ou DELETE sans WHERE | Toute la table modifiée | Tester le WHERE avec un SELECT |
| Sous-requête scalaire qui renvoie plusieurs lignes | Erreur 1242 | IN, ou un agrégat dans la sous-requête |
| Moyenne de moyennes | Résultat faux | Moyenne directe sur les lignes |
| Agrégat après jointure de deux tables enfants | Comptes multipliés | COUNT(DISTINCT …) ou agrégation préalable |
Avant de rendre ta copie, vérifie pour chaque requête :
- Elle répond à la question posée, toute la question (le tri demandé, les colonnes demandées).
- Chaque table du
FROMest reliée par une condition de jointure. - Le type de jointure correspond aux mots de l'énoncé.
- Chaque colonne du
SELECTest dans leGROUP BYou dans un agrégat. - Les filtres sur les lignes sont dans
WHERE, ceux sur les groupes dansHAVING. - Les
NULLsont traités avecIS NULLetCOALESCE. - Les chaînes et les dates sont entre apostrophes simples.
- Les noms de tables et de colonnes sont exactement ceux du schéma.
Écrire du SQL lisible sur papier
Le correcteur lit des dizaines de copies : une requête claire est plus facile à comprendre, donc à valoriser, même avec une petite erreur de syntaxe.
- Mots-clés en majuscules, noms de tables et de colonnes comme dans le schéma.
- Une clause par ligne (
SELECT,FROM, chaqueJOIN,WHERE,GROUP BY…), et les conditions d'unWHERElong sur des lignes séparées. - Des alias courts mais évocateurs (
tpour ticket,techetdempour deux rôles d'employé). - Les sous-requêtes indentées sous la clause qui les contient.
- Une ligne de commentaire (
-- …) quand une astuce n'est pas évidente : unLEFT JOINvoulu, unCOALESCE.
Exercices
Exercice 1 sur 3 Appliquer la méthode Réussi À revoir
Question type : « Afficher, pour chaque technicien, son nom, le nombre de tickets différents sur lesquels il est intervenu et le temps total passé, en heures avec une décimale, en ne gardant que les techniciens qui ont travaillé sur au moins 4 tickets différents. Trier par temps décroissant. »
Déroule les quatre temps, puis écris la requête.
Voir la réponseMasquer la réponse de l'exercice 1
- Tables :
intervention(tickets, durées) etemploye(nom du technicien). - Jointure :
intervention.id_technicien→employe.id_employe, interne (on ne veut que les techniciens qui sont intervenus). - Filtres : aucun sur les lignes ; regroupement par technicien ; condition sur un agrégat, donc
HAVING COUNT(DISTINCT i.id_ticket) >= 4. - Présentation : nom, nombre de tickets,
ROUND(SUM(duree_min) / 60, 1), tri décroissant.
SELECT e.nom,
COUNT(DISTINCT i.id_ticket) AS nb_tickets,
ROUND(SUM(i.duree_min) / 60, 1) AS heures
FROM intervention i
JOIN employe e ON e.id_employe = i.id_technicien
GROUP BY e.id_employe, e.nom
HAVING COUNT(DISTINCT i.id_ticket) >= 4
ORDER BY heures DESC;
| nom | nb_tickets | heures |
|---|---|---|
| Mercier | 4 | 8.5 |
| Diallo | 6 | 7.5 |
| Lambert | 5 | 4.9 |
« Tickets différents » impose DISTINCT : Moussa Diallo a fait 7 interventions sur 6 tickets. Avec PostgreSQL ou SQL Server, SUM(i.duree_min) / 60 serait une division entière : écris / 60.0.
Tu avais trouvé ?
Exercice 2 sur 3 Interne, externe ou anti-jointure Réussi À revoir
Pour chaque énoncé, choisis entre jointure interne, jointure externe et anti-jointure (ou NOT EXISTS), sans écrire la requête.
- « Afficher les postes avec le nom de leur utilisateur. »
- « Afficher tous les logiciels avec leur nombre d'installations. »
- « Afficher les techniciens qui ne sont jamais intervenus sur un ticket critique. »
- « Afficher chaque service et le nombre de ses employés, y compris les services vides. »
- « Afficher les employés qui ont ouvert au moins un ticket de priorité haute. »
Voir la réponseMasquer la réponse de l'exercice 2
- Interne : la phrase ne dit pas « tous les postes ». Si l'on voulait aussi les postes en stock, ce serait une jointure externe. En cas de doute à l'examen, écris en une ligne l'interprétation que tu retiens.
- Externe (
logiciel LEFT JOIN installation) : « tous » inclut Acrobat Pro, jamais installé, avec 0. - Anti-jointure : « jamais » se traduit par
NOT EXISTS(ouLEFT JOIN … WHERE … IS NULL), avec la condition sur la priorité dans la sous-requête. - Externe depuis
service, avecCOUNT(e.id_employe)pour obtenir 0. - Interne, avec
DISTINCTouEXISTS: un employé qui a ouvert deux tickets de priorité haute ne doit apparaître qu'une fois.
Tu avais trouvé ?
Exercice 3 sur 3 Trouver le chemin de jointure Réussi À revoir
Question : « Afficher le nom des employés du service Comptabilité et les logiciels installés sur leurs postes. » Donne les tables nécessaires, le chemin de jointure, puis la requête.
Voir la réponseMasquer la réponse de l'exercice 3
Tables : service (filtre sur le libellé), employe (nom), poste (lien entre l'employé et ses installations), installation, logiciel (nom du logiciel). Chemin : service ← employe ← poste ← installation → logiciel. Les tables poste et installation n'apportent aucune colonne affichée, mais sans elles il n'existe aucun lien entre un employé et un logiciel.
SELECT e.nom, l.nom AS logiciel
FROM service s
JOIN employe e ON e.id_service = s.id_service
JOIN poste p ON p.id_employe = e.id_employe
JOIN installation i ON i.id_poste = p.id_poste
JOIN logiciel l ON l.id_logiciel = i.id_logiciel
WHERE s.libelle = 'Comptabilité'
ORDER BY e.nom, logiciel;
| nom | logiciel |
|---|---|
| Lefèvre | Firefox |
| Lefèvre | Microsoft 365 |
| Lefèvre | Sage 100 Comptabilité |
| Morel | Firefox |
| Morel | Microsoft 365 |
| Morel | Odoo |
| Morel | Sage 100 Comptabilité |
Paul Martin n'apparaît pas : il n'a pas encore de poste. Avec des LEFT JOIN à partir de employe, il apparaîtrait avec NULL.
Tu avais trouvé ?