Aller au contenu

Un mot pour Fahmio

Tu écris. Tu continues.

Un problème, une idée — assez pour qu’on comprenne, puis tu retournes à ta copie.

On lit. Tu n’as rien d’autre à faire.

Où veux-tu aller ?

↑ ↓ pour parcourir · Entrée pour ouvrir · Échap pour fermer

Fahmio
Fahmio
Bac Tunisie
BD-JBases de données et SQL

Interpréter une requête donnée : table résultat sur des extraits, rôle, ajout d'un HAVING, équivalent sans IN, associer requêtes et rôles

Idée directrice

C'est le sens inverse de l'écriture de requêtes : le sujet donne une requête SQL et de petits extraits de tables, et fait écrire la table résultat avec ses noms de colonnes, puis le rôle de la requête en une phrase « pour chaque …, afficher … ». Il enchaîne sur une transformation (ajouter un HAVING, remplacer IN par une jointure) ou sur la lecture fine de requêtes courtes à associer à leur rôle. On exécute la requête à la main dans l'ordre du SGBD : jointure, WHERE, GROUP BY, agrégats, HAVING.

Ce qui aide à reconnaître la démarche

« donner le résultat de l'exécution de la requête R … tout en indiquant les noms des colonnes » ; « En déduire le rôle de la requête » ; « Donner une requête SQL équivalente à la requête R, sans utiliser l'opérateur IN » ; « compléter la colonne « Réponse » avec la lettre correspondante à son rôle » ; « En exécutant la requête …, le système : »

Besoin d’un point de départ ? Voir la méthode
  • Résultat d'une requête : faire la jointure sur les extraits (seules les lignes appariées restent), appliquer WHERE, former les groupes, calculer les agrégats, filtrer par HAVING ; écrire les noms de colonnes (alias).
  • Rôle : une phrase « pour chaque …, afficher … » qui nomme ce qui est affiché et ce qui est filtré, sans relire le code ligne à ligne.
  • Condition sur un agrégat → HAVING après GROUP BY ; condition sur une ligne → WHERE.
  • IN (SELECT …) → jointure sur la même colonne, avec DISTINCT si une ligne peut correspondre plusieurs fois.
  • Associer requête et rôle : vérifier la commande (LMD ou LDD), la colonne du critère (code, nom, ville), les jokers de LIKE et la présence du WHERE.
Les pièges à vérifier dans ta démarche

Afficher un musée sans visite (la jointure l'élimine) ; oublier la ligne des noms de colonnes ou les alias ; écrire la condition sur SUM dans WHERE ; oublier DISTINCT dans la jointure qui remplace IN ; confondre 'S%' (commence par), '%S' (se termine par) et '%S%' (contient) ; prendre la ville pour le nom du musée ; lire MODIFY … DEFAULT comme un changement de type.

Sujet principal

Exercice (6 points) — dans l'esprit des sessions 2023–2025, section Sciences de l'informatique

18 questionsCorrigé masqué

L'agence Patrimoine Vivant organise des visites guidées de groupes dans les musées tunisiens. Elle utilise la base de données Gestion_Musees :

  • Musee ( codeMusee , nomMusee , ville )
  • Guide ( codeGuide , nomGuide , langue )
  • Visite ( numVisite , dateVisite , nbVisiteurs , codeMusee# , codeGuide# )
ChampDescription
nomMuseeNom d'un musée, chaîne de 40 caractères.
langueLangue dans laquelle un guide commente les visites, chaîne de 15 caractères.
dateVisiteDate d'une visite.
nbVisiteursNombre de personnes d'un groupe, entier.

Extraits des tables :

Table Musee

codeMuseenomMuseeville
M01Musée du BardoTunis
M02Musée de CarthageCarthage
M03Musée d'El JemEl Jem
M04Musée de SousseSousse

Table Guide

codeGuidenomGuidelangue
G1Amri SamiAnglais
G2Chaouch LeilaFrançais
G3Ferjani OlfaItalien
G4Sahli YoussefAllemand

Table Visite

numVisitedateVisitenbVisiteurscodeMuseecodeGuide
12025-03-0225M01G2
22025-03-0240M03G1
32025-03-0518M01G3
42025-03-0932M02G2
52025-03-1230M01G1
62025-03-1522M03G1
72025-03-1615M03G3

Requête R :

SELECT nomMusee,
       COUNT(numVisite) AS nbGroupes,
       SUM(nbVisiteurs) AS total
FROM Musee M, Visite V
WHERE M.codeMusee = V.codeMusee
GROUP BY nomMusee;

Requête R2 :

SELECT codeGuide, nomGuide
FROM Guide
WHERE codeGuide IN (SELECT codeGuide
                    FROM Visite
                    WHERE codeMusee = 'M03');

Liste des rôles (question 5) :

  • a. Modifier la langue de tous les guides.
  • b. Afficher la date et le nombre de visiteurs des visites du musée dont le nom est « Tunis ».
  • c. Ajouter un nouveau guide avec des valeurs spécifiques.
  • d. Supprimer les guides dont le nom contient la lettre « S ».
  • e. Modifier le type du champ « nbVisiteurs » de la table « Visite ».
  • f. Afficher la date et le nombre de visiteurs des visites effectuées dans les musées situés à Tunis.
  • g. Modifier la valeur par défaut du champ « nbVisiteurs » de la table « Visite ».
  • h. Supprimer les guides dont le nom commence par la lettre « S ».
  • i. Ajouter une contrainte de domaine sur un champ de la table « Visite ».
  • j. Modifier la langue du guide dont le code est spécifié.

Requêtes de la question 5 :

-- Q1
INSERT INTO Guide
VALUES ('G5', 'Hamdi Sonia', 'Espagnol');
-- Q2
SELECT dateVisite, nbVisiteurs
FROM Visite V, Musee M
WHERE V.codeMusee = M.codeMusee
  AND ville = 'Tunis';
-- Q3
UPDATE Guide SET langue = 'Anglais'
WHERE codeGuide = 'G3';
-- Q4
DELETE FROM Guide
WHERE nomGuide LIKE 'S%';
-- Q5
ALTER TABLE Visite
ADD CHECK (nbVisiteurs BETWEEN 1 AND 50);
-- Q6
ALTER TABLE Visite
MODIFY nbVisiteurs INT DEFAULT 20;
  1. En se basant sur les extraits fournis, donner le résultat de l'exécution de la requête R, en indiquant les noms des colonnes affichées.
  2. En déduire le rôle de la requête R.
  3. Réécrire la requête R en apportant les modifications nécessaires pour n'afficher que les musées ayant accueilli, au total, au moins 70 visiteurs.
  4. On s'intéresse à la requête R2.
    1. Donner le résultat de son exécution sur les extraits fournis.
    2. En déduire son rôle.
    3. Donner une requête SQL équivalente à R2, sans utiliser l'opérateur IN.
  5. Pour chacune des requêtes Q1 à Q6, donner la lettre correspondant à son rôle dans la liste proposée.
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : la jointure ne garde que les visites appariées à un musée ; GROUP BY nomMusee forme un groupe par musée visité, COUNT compte ses visites et SUM additionne ses visiteurs.

nomMuseenbGroupestotal
Musée du Bardo373 (25 + 18 + 30)
Musée d'El Jem377 (40 + 22 + 15)
Musée de Carthage132

Le Musée de Sousse n'apparaît pas : aucune visite ne le référence dans l'extrait. Sans ORDER BY, l'ordre des lignes n'est pas imposé.

2. La requête R affiche, pour chaque musée ayant reçu au moins une visite, son nom, le nombre de groupes accueillis et le nombre total de visiteurs.

3. Idée : la condition porte sur un total calculé par groupe : elle se place dans HAVING, après GROUP BY, jamais dans WHERE.

SELECT nomMusee,
       COUNT(numVisite) AS nbGroupes,
       SUM(nbVisiteurs) AS total
FROM Musee M, Visite V
WHERE M.codeMusee = V.codeMusee
GROUP BY nomMusee
HAVING SUM(nbVisiteurs) >= 70;

Sur l'extrait, restent le Musée du Bardo (73) et le Musée d'El Jem (77) ; le Musée de Carthage (32) est éliminé.

4.a Idée : exécuter d'abord la sous-requête : elle renvoie les guides des visites du musée M03, soit G1, G1 et G3 (visites 2, 6 et 7).

codeGuidenomGuide
G1Amri Sami
G3Ferjani Olfa

4.b R2 affiche le code et le nom des guides ayant encadré au moins une visite au musée de code « M03 ».

4.c Idée : IN se remplace par une jointure Guide–Visite ; G1 ayant encadré deux visites à M03, la jointure le produirait deux fois : DISTINCT rétablit le résultat de R2.

SELECT DISTINCT G.codeGuide, nomGuide
FROM Guide G, Visite V
WHERE G.codeGuide = V.codeGuide
  AND codeMusee = 'M03';

5. Idée : pour chaque requête, vérifier la commande, la colonne sur laquelle porte le critère et la forme exacte du motif LIKE.

RequêteRéponseJustification
Q1cinsertion de valeurs données dans Guide
Q2fle critère porte sur la ville du musée ; b supposerait nomMusee = 'Tunis'
Q3jle WHERE vise un seul guide ; a correspondrait à un UPDATE sans WHERE
Q4h'S%' : le nom commence par S ; « contient » (d) s'écrirait '%S%'
Q5iCHECK ajoute une contrainte de domaine
Q6gnbVisiteurs reste de type INT (e ne convient pas) : seule la valeur par défaut change

Changer d’énoncé, garder le raisonnement

Choisis un seul transfert après le sujet principal. Qu’est-ce qui change ? Quel résultat ou quelle méthode peux-tu réutiliser ? Les autres exercices restent disponibles pour une prochaine séance.

Variantes rencontrées : V/F sur des requêtes proposées pour une situation (contrôle et principale 2022) ; effet de UPDATE sans WHERE, de DROP TABLE, de LIKE '%3' et d'un regroupement (contrôle 2023) ; effet de DELETE sans WHERE, d'un INSERT incomplet, de = '4%' et de ORDER BY 2 (principale 2023) ; résultat et rôle d'une requête GROUP BY … HAVING (contrôle 2024) ; résultat, rôle et équivalent sans IN (principale 2024) ; résultat, rôle et ajout d'un HAVING (contrôle 2025) ; six requêtes associées à dix rôles (principale 2025). Les séries de classe posent aussi la question « Que fait cette requête ? ».

Exercices d'entraînement — une nuance à la fois

1 Drill BD-J.1 — ORDER BY n dans une requête SELECT : la position d'une colonne affichée
Entraînement 01 / 05

Drill BD-J.1 — ORDER BY n dans une requête SELECT : la position d'une colonne affichée

4 questionsCorrigé masqué

Un ciné-club de Bizerte enregistre les films qu'il projette dans la table Film ( idFilm , titre , annee , duree ), la durée étant en minutes. Extrait :

idFilmtitreanneeduree
11Le Vent du Sud201998
12La Médina bleue2021112
13Retour à Kerkennah2019105
14Les Oliviers de Zarzis202398
15Nuit à Tabarka202187

Requêtes :

-- R1
SELECT titre, duree
FROM Film
ORDER BY 2, 1;
-- R2
SELECT annee, titre
FROM Film
ORDER BY 1 DESC, 2;
-- R3
SELECT titre
FROM Film
ORDER BY 2;
  1. Donner le résultat de l'exécution de R1 sur l'extrait.
  2. Donner le résultat de l'exécution de R2 sur l'extrait.
  3. Réécrire R2 en nommant les colonnes du ORDER BY au lieu de leur position.
  4. Que se passe-t-il à l'exécution de R3 ? Justifier.
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : dans ORDER BY, un nombre désigne la position d'une colonne de la liste du SELECT : 2 est duree, 1 est titre ; le second critère départage les égalités.

titreduree
Nuit à Tabarka87
Le Vent du Sud98
Les Oliviers de Zarzis98
Retour à Kerkennah105
La Médina bleue112

Les deux films de 98 minutes sont rangés par titre croissant : « Le Vent… » précède « Les Oliviers… » (l'espace se classe avant la lettre s).

2. Idée : 1 DESC trie par année décroissante, puis 2 range par titre croissant les films d'une même année.

anneetitre
2023Les Oliviers de Zarzis
2021La Médina bleue
2021Nuit à Tabarka
2019Le Vent du Sud
2019Retour à Kerkennah

3.

SELECT annee, titre
FROM Film
ORDER BY annee DESC, titre;

4. R3 n'affiche qu'une colonne : la position 2 n'existe pas dans la liste du SELECT, le SGBD signale une erreur. Le nombre ne désigne jamais une colonne de la table.

2 Drill BD-J.2 — DELETE, DROP TABLE, ALTER … DROP : ce qui reste après chaque requête
Entraînement 02 / 05

Drill BD-J.2 — DELETE, DROP TABLE, ALTER … DROP : ce qui reste après chaque requête

2 questionsCorrigé masqué

Un restaurant de Djerba enregistre ses réservations dans la table Reservation ( idRes , dateRes , nbPlaces , idClient ). Contenu actuel :

idResdateResnbPlacesidClient
12025-07-012C10
22025-07-015C11
32025-07-023C10
42025-07-038C12
52025-07-034C13
62025-07-046C11

Chacune des requêtes suivantes est exécutée seule, sur la table dans l'état ci-dessus :

-- a)
DELETE FROM Reservation
WHERE nbPlaces > 4;
-- b)
DELETE FROM Reservation;
-- c)
DROP TABLE Reservation;
-- d)
ALTER TABLE Reservation
DROP nbPlaces;
-- e)
DELETE nbPlaces FROM Reservation;
  1. Pour chaque requête, indiquer si la table Reservation existe encore après son exécution, et si oui, son nombre de lignes et son nombre de colonnes. Signaler la requête qui provoque une erreur.
  2. Laquelle de ces requêtes faut-il utiliser pour vider la table de ses réservations en conservant sa structure ?
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : DELETE agit sur les lignes (avec ou sans WHERE), DROP TABLE détruit la table, ALTER TABLE … DROP retire une colonne à toutes les lignes.

RequêteTable existante ?LignesColonnes
aoui3 (les réservations 1, 3 et 5)4
boui04
cnon——
doui63
eerreur——

a) supprime les réservations de plus de 4 places (2, 4 et 6). e) est refusée : DELETE supprime des lignes entières, on ne peut pas y nommer une colonne ; retirer un champ s'écrit avec ALTER TABLE … DROP, comme en d).

2. La requête b) : DELETE FROM Reservation; supprime toutes les lignes et garde la table avec ses quatre colonnes ; DROP TABLE la ferait disparaître.

3 Drill BD-J.3 — Vrai ou faux : la requête proposée répond-elle à la situation ?
Entraînement 03 / 05

Drill BD-J.3 — Vrai ou faux : la requête proposée répond-elle à la situation ?

1 questionCorrigé masqué

Une salle de sport de Nabeul gère ses abonnés dans la table Abonne ( idAb , nomAb , ville , tel , dateInsc ), où dateInsc est de type date et où le téléphone peut rester vide.

Pour chacune des situations suivantes, répondre par V si la requête SQL proposée répond à la situation, ou par F dans le cas contraire.

Situation 1 — Compter les abonnés de la ville de « Nabeul ».

-- 1)
SELECT COUNT(*) FROM Abonne
WHERE ville = 'Nabeul';
-- 2)
SELECT COUNT(idAb) FROM Abonne
WHERE ville = 'Nabeul';
-- 3)
SELECT COUNT(tel) FROM Abonne
WHERE ville = 'Nabeul';
-- 4)
SELECT COUNT(*) FROM Abonne
HAVING ville = 'Nabeul';

Situation 2 — Afficher les abonnés inscrits au cours de l'année 2024.

-- 1)
SELECT * FROM Abonne
WHERE YEAR(dateInsc) = 2024;
-- 2)
SELECT * FROM Abonne
WHERE dateInsc BETWEEN '2024-01-01'
                   AND '2024-12-31';
-- 3)
SELECT * FROM Abonne
WHERE dateInsc BETWEEN '2024-01-01'
                   OR '2024-12-31';
-- 4)
SELECT * FROM Abonne
WHERE dateInsc > '2024-01-01'
  AND dateInsc < '2024-12-31';

Situation 3 — Remplacer par « Hammamet » la ville de l'abonné d'identifiant 315.

-- 1)
UPDATE Abonne SET ville = 'Hammamet'
WHERE idAb = 315;
-- 2)
ALTER TABLE Abonne
SET ville = 'Hammamet'
WHERE idAb = 315;
-- 3)
UPDATE Abonne SET ville = 'Hammamet';
-- 4)
UPDATE Abonne SET ville = 'Hammamet'
WHERE idAb IN (315);
Voir la correction commentéeAprès avoir posé votre démarche

Situation 1. Idée : COUNT() et COUNT(clé) comptent les lignes ; COUNT(colonne) ignore les valeurs vides.*

  • 1) V.
  • 2) V : idAb, clé primaire, n'est jamais vide.
  • 3) F : les abonnés de Nabeul sans téléphone ne sont pas comptés.
  • 4) F : HAVING filtre des groupes ; une condition sur chaque ligne s'écrit dans WHERE.

Situation 2. Idée : BETWEEN inclut ses deux bornes ; des inégalités strictes les excluent.

  • 1) V.
  • 2) V : du 1er janvier au 31 décembre 2024 inclus.
  • 3) F : BETWEEN s'écrit avec AND ; la requête est refusée.
  • 4) F : les abonnés inscrits le 1er janvier ou le 31 décembre 2024 sont perdus.

Situation 3. Idée : modifier des données, c'est UPDATE … SET … WHERE ; ALTER TABLE modifie la structure.

  • 1) V.
  • 2) F : ALTER TABLE ne modifie pas les valeurs, la requête est refusée.
  • 3) F : sans WHERE, la ville de tous les abonnés devient Hammamet.
  • 4) V : IN (315) équivaut à = 315.
4 Drill BD-J.4 — WHERE filtre les lignes, HAVING filtre les groupes
Entraînement 04 / 05

Drill BD-J.4 — WHERE filtre les lignes, HAVING filtre les groupes

4 questionsCorrigé masqué

Une pâtisserie de Sousse enregistre ses commandes dans les tables Client ( idClient , nomClient ) et Commande ( numCde , dateCde , montant , idClient# ), le montant étant en dinars. Extraits :

idClientnomClient
C1Ben Ali Hana
C2Saidi Karim
C3Jaziri Nour
numCdedateCdemontantidClient
5012025-05-0245.000C1
5022025-05-02120.000C2
5032025-05-0330.000C1
5042025-05-0485.000C3
5052025-05-0560.000C1
5062025-05-0625.000C2
-- R1
SELECT nomClient, COUNT(numCde) AS nb
FROM Client C, Commande D
WHERE C.idClient = D.idClient
  AND montant >= 50
GROUP BY nomClient;
-- R2
SELECT nomClient, COUNT(numCde) AS nb
FROM Client C, Commande D
WHERE C.idClient = D.idClient
GROUP BY nomClient
HAVING COUNT(numCde) >= 2;
  1. Donner le résultat de l'exécution de R1 sur les extraits, avec les noms des colonnes.
  2. Donner le résultat de l'exécution de R2.
  3. En déduire le rôle de chacune des deux requêtes.
  4. Un élève propose, pour obtenir le résultat de R2, de remplacer HAVING par la condition AND COUNT(numCde) >= 2 placée dans le WHERE. Sa requête est refusée : pourquoi ?
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : WHERE agit avant le regroupement : seules les commandes d'au moins 50 D (502, 504, 505) sont comptées.

nomClientnb
Ben Ali Hana1
Saidi Karim1
Jaziri Nour1

2. Idée : toutes les commandes sont regroupées par client, puis HAVING élimine les groupes de moins de deux commandes.

nomClientnb
Ben Ali Hana3
Saidi Karim2

Jaziri Nour, avec une seule commande, est éliminée.

3. R1 affiche, pour chaque client ayant passé au moins une commande d'au moins 50 dinars, son nom et le nombre de ces commandes ; R2 affiche le nom et le nombre de commandes des clients ayant passé au moins deux commandes.

4. COUNT est une fonction d'agrégat : elle se calcule sur un groupe, qui n'existe pas encore quand WHERE examine les lignes une à une. Une condition sur un agrégat se place dans HAVING.

5 Drill BD-J.5 — IN sur une sous-requête groupée : résultat, rôle, équivalent par jointure
Entraînement 05 / 05

Drill BD-J.5 — IN sur une sous-requête groupée : résultat, rôle, équivalent par jointure

4 questionsCorrigé masqué

Une plateforme de covoiturage enregistre ses conducteurs et leurs trajets dans les tables Conducteur ( idCond , nomCond , ville ) et Trajet ( idTrajet , dateTrajet , villeDep , villeArr , idCond# ). Extraits :

idCondnomCondville
D1Hamza BelhajSousse
D2Ines MaalejSfax
D3Walid KarouiTunis
D4Rania SfarSousse
idTrajetdateTrajetvilleDepvilleArridCond
712025-06-01SousseTunisD1
722025-06-01SfaxGabèsD2
732025-06-03TunisBizerteD3
742025-06-04SousseMonastirD1
752025-06-05SfaxTunisD2
762025-06-07SousseKairouanD1

Requête R :

SELECT idCond, nomCond
FROM Conducteur
WHERE idCond IN (SELECT idCond
                 FROM Trajet
                 GROUP BY idCond
                 HAVING COUNT(*) >= 2);
  1. Donner le résultat de l'exécution de R sur les extraits.
  2. En déduire le rôle de R.
  3. Donner une requête équivalente à R, sans utiliser l'opérateur IN.
  4. On souhaite afficher en plus le nombre de trajets de chaque conducteur retenu. Expliquer pourquoi la forme avec IN ne le permet pas, puis compléter la requête de la question 3.
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : la sous-requête compte les trajets par conducteur et ne garde que ceux qui en ont au moins deux : D1 (3 trajets) et D2 (2 trajets).

idCondnomCond
D1Hamza Belhaj
D2Ines Maalej

2. R affiche l'identifiant et le nom des conducteurs ayant proposé au moins deux trajets.

3. Idée : joindre Conducteur et Trajet, regrouper par conducteur et reporter la condition dans HAVING.

SELECT C.idCond, nomCond
FROM Conducteur C, Trajet T
WHERE C.idCond = T.idCond
GROUP BY C.idCond, nomCond
HAVING COUNT(*) >= 2;

4. Dans R, le nombre de trajets n'est calculé que dans la sous-requête : la requête principale ne lit que Conducteur et ne peut pas l'afficher. Avec la jointure, le groupe de chaque conducteur est disponible :

SELECT C.idCond, nomCond,
       COUNT(*) AS nbTrajets
FROM Conducteur C, Trajet T
WHERE C.idCond = T.idCond
GROUP BY C.idCond, nomCond
HAVING COUNT(*) >= 2;

Résultat : D1, Hamza Belhaj, 3 ; D2, Ines Maalej, 2.

Relier ce raisonnement au bac

Choisis une filière pour voir les sujets qui étayent ce scénario.