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-FBases de données et SQL

Requêtes SELECT d'examen sur un schéma de sept tables : DISTINCT, dates, tri, GROUP BY et HAVING, NOT IN, sous-requête MAX ou AVG

Idée directrice

Dans la partie « manipulation des données » des sujets de la section Sciences de l'informatique, cinq à neuf questions en langage naturel portent sur un même schéma (« Quels sont… ? On affichera les champs… »). Chaque question cache une décision : quelles tables relier, y compris une table intermédiaire dont rien n'est affiché ; faut-il DISTINCT, un filtre de date, un tri ; un regroupement (« pour chaque », « le nombre de ») avec éventuellement HAVING (condition sur un total) ; une sous-requête (« le plus », « supérieur à la moyenne ») ou un NOT IN (« qui n'ont pas »). On repère le mot déclencheur, puis on écrit la requête.

Ce qui aide à reconnaître la démarche

« Écrire en SQL les requêtes permettant de répondre aux questions suivantes » ; « On affichera les champs » ; « Quel est le nombre de … pour chaque … » ; « dont le revenu total … dépasse strictement » ; « qui n'ont pas été loués pendant l'année » ; « ayant le prix de location le plus élevé »

Besoin d’un point de départ ? Voir la méthode
  • Lire d'abord « On affichera » : ce sont les colonnes du SELECT ; chercher ensuite les tables qui portent ces colonnes et celles des conditions.
  • Relier les tables par clé étrangère = clé primaire, en passant par les tables intermédiaires : n tables dans le FROM, n − 1 conditions de jointure ; préfixer une colonne présente dans deux tables.
  • Mots déclencheurs : « sans répétition » → DISTINCT ; « pour chaque », « le nombre de », « le total » → GROUP BY sur toutes les colonnes affichées non agrégées ; « dont le total / le nombre dépasse » → HAVING ; « le plus », « le moins » → = (SELECT MAX / MIN …) ; « supérieur à la moyenne » → > (SELECT AVG …) ; « qui n'ont pas », « aucun », « jamais » → NOT IN (SELECT …).
  • Dates : YEAR(), MONTH(), BETWEEN (bornes incluses) ; tri : ORDER BY … ASC ou DESC, en dernière clause.
Les pièges à vérifier dans ta démarche

Oublier une table intermédiaire ou une condition de jointure (produit cartésien) ; mettre une condition sur COUNT ou SUM dans WHERE ; afficher une colonne non agrégée absente du GROUP BY ; traduire « qui n'ont pas » par une jointure avec <> ; écrire dureeMin = MAX(dureeMin) sans sous-requête ; oublier DISTINCT quand la jointure multiplie les lignes ; laisser une colonne ambiguë (numAbonne présent dans Abonne et dans Trajet).

Sujet principal

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

8 questionsFigure fournieCorrigé masqué

VéloCité est le service municipal de vélos en libre-service de la ville de Sfax. Chaque abonné a choisi une formule d'abonnement et emprunte des vélos stationnés dans les stations de la ville ; chaque vélo est d'un modèle donné et peut faire l'objet de réparations. La base de données simplifiée du service a la représentation graphique suivante :

ChampDescription
idStationIdentifiant d'une station, entier.
nomStationNom d'une station, chaîne de 20 caractères.
quartierQuartier où se trouve une station, chaîne de 30 caractères.
capaciteNombre maximal de vélos d'une station, entier.
codeModeleCode d'un modèle de vélo, chaîne de 4 caractères.
libModeleLibellé d'un modèle, chaîne de 30 caractères.
typeModeleType d'un modèle, « Classique » ou « Electrique », chaîne de 10 caractères.
tarifMinutePrix d'une minute de trajet, en dinars, réel.
idVeloIdentifiant d'un vélo, entier.
dateServiceDate de mise en service d'un vélo.
codeFormuleCode d'une formule d'abonnement, chaîne de 3 caractères.
libFormuleLibellé d'une formule (Journalier, Mensuel, Annuel…), chaîne de 20 caractères.
prixMensuelPrix mensuel d'une formule, en dinars, réel.
numAbonneNuméro d'un abonné, entier.
nomAbonneNom et prénom d'un abonné, chaîne de 40 caractères.
telAbonneTéléphone d'un abonné, chaîne de 8 caractères.
emailAbonneAdresse mail d'un abonné, chaîne de 50 caractères.
idTrajetIdentifiant d'un trajet, entier.
dateTrajetDate d'un trajet (sans heure).
dureeMinDurée d'un trajet, en minutes, entier.
montantMontant payé pour un trajet, en dinars, réel.
dateRepDate d'une réparation.
panneDescription de la panne réparée, chaîne de 50 caractères.
coutCoût d'une réparation, en dinars, réel.

On suppose que la base de données est déjà créée et contient des données. Écrire en SQL les requêtes permettant de répondre aux questions suivantes :

  1. Quels sont les abonnés ayant emprunté au moins une fois un vélo de type « Electrique » ? On affichera, sans répétition, les champs nomAbonne et telAbonne.
  2. Quels sont les trajets effectués entre le 1er et le 15 mars 2026 dont la durée dépasse 40 minutes ? On affichera les champs idTrajet, dateTrajet et dureeMin.
  3. Quels sont les vélos stationnés dans le quartier « Sfax Jadida » ? On affichera les champs idVelo, libModele et nomStation ; la liste sera triée de la mise en service la plus récente à la plus ancienne.
  4. Quel est le nombre de vélos stationnés dans chaque station ? On affichera les champs idStation et nomStation ainsi que le nombre de vélos.
  5. Quels sont les abonnés dont le montant total des trajets effectués en 2025 dépasse strictement 60 dinars ? On affichera les champs numAbonne et nomAbonne ainsi que ce montant total.
  6. Quels sont les abonnés qui n'ont effectué aucun trajet au cours du mois de janvier 2026 ? On affichera les champs numAbonne et nomAbonne.
  7. Quels sont les trajets ayant la durée la plus longue ? On affichera les champs idTrajet, nomAbonne et dureeMin.
  8. Quelles sont les réparations dont le coût dépasse le coût moyen de toutes les réparations ? On affichera les champs idVelo, dateRep, panne et cout.
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : le type est dans Modele, l'abonné dans Abonne ; aucune colonne commune : on traverse Trajet et Velo, dont rien n'est affiché. Un abonné qui a fait plusieurs trajets électriques apparaîtrait plusieurs fois, d'où DISTINCT (« sans répétition »).

SELECT DISTINCT nomAbonne, telAbonne
FROM Abonne A, Trajet T, Velo V, Modele M
WHERE A.numAbonne = T.numAbonne
  AND T.idVelo = V.idVelo
  AND V.codeModele = M.codeModele
  AND typeModele = 'Electrique';

Quatre tables dans le FROM, donc trois conditions de jointure (clé étrangère = clé primaire).

2. Idée : dateTrajet est une date sans heure : BETWEEN inclut les deux bornes, le 15 mars compris.

SELECT idTrajet, dateTrajet, dureeMin
FROM Trajet
WHERE dateTrajet BETWEEN '2026-03-01'
                     AND '2026-03-15'
  AND dureeMin > 40;

Équivalent : dateTrajet >= '2026-03-01' AND dateTrajet <= '2026-03-15'.

3. Idée : le quartier est dans Station et le libellé dans Modele : deux jointures autour de Velo. « De la plus récente à la plus ancienne » : tri décroissant sur dateService, même si ce champ n'est pas affiché.

SELECT idVelo, libModele, nomStation
FROM Velo V, Modele M, Station S
WHERE V.codeModele = M.codeModele
  AND V.idStation = S.idStation
  AND quartier = 'Sfax Jadida'
ORDER BY dateService DESC;

4. Idée : « le nombre … de chaque station » : un groupe par station. Les colonnes affichées sans fonction d'agrégat (idStation, nomStation) figurent toutes dans le GROUP BY.

SELECT S.idStation, nomStation,
       COUNT(idVelo) AS nbVelos
FROM Station S, Velo V
WHERE S.idStation = V.idStation
GROUP BY S.idStation, nomStation;

idStation existe dans Station et dans Velo : elle est préfixée. La jointure ne garde que les couples station–vélo existants : une station vide n'apparaît pas.

5. Idée : l'année porte sur chaque trajet, c'est un filtre de lignes (WHERE, avant le regroupement) ; « total > 60 » porte sur une somme calculée par abonné, c'est un filtre de groupes (HAVING, après le regroupement).

SELECT A.numAbonne, nomAbonne,
       SUM(montant) AS total
FROM Abonne A, Trajet T
WHERE A.numAbonne = T.numAbonne
  AND YEAR(dateTrajet) = 2025
GROUP BY A.numAbonne, nomAbonne
HAVING SUM(montant) > 60;

6. Idée : « aucun trajet » : on construit d'abord la liste des abonnés qui ont roulé en janvier 2026 (sous-requête), puis on garde ceux qui n'y figurent pas.

SELECT numAbonne, nomAbonne
FROM Abonne
WHERE numAbonne NOT IN (
    SELECT numAbonne FROM Trajet
    WHERE YEAR(dateTrajet) = 2026
      AND MONTH(dateTrajet) = 1);

Une jointure écrite avec A.numAbonne <> T.numAbonne ne convient pas : elle associe chaque abonné aux trajets des autres et le ferait apparaître dès que quelqu'un d'autre a roulé en janvier.

7. Idée : « la plus longue » : chaque durée est comparée au maximum calculé par une sous-requête ; si plusieurs trajets sont à égalité, ils sont tous affichés.

SELECT idTrajet, nomAbonne, dureeMin
FROM Trajet T, Abonne A
WHERE T.numAbonne = A.numAbonne
  AND dureeMin = (SELECT MAX(dureeMin)
                  FROM Trajet);

WHERE dureeMin = MAX(dureeMin) est refusé (fonction d'agrégat dans WHERE), et SELECT idTrajet, nomAbonne, MAX(dureeMin) … ne répond pas : MAX résume toutes les lignes en une seule et le nom affiché n'est pas forcément celui du trajet le plus long (MySQL, en mode ONLY_FULL_GROUP_BY activé par défaut, refuse même cette requête).

8. Idée : le coût moyen n'est pas connu à l'avance : une sous-requête AVG le calcule, puis chaque coût lui est comparé.

SELECT idVelo, dateRep, panne, cout
FROM Reparation
WHERE cout > (SELECT AVG(cout)
              FROM Reparation);

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 : chaîne de jointures à travers une table dont rien n'est affiché (contrôle 2020 : interventions d'un client via la télévision ; contrôle 2025 : forêts d'un gouvernorat) ; « le plus » par sous-requête MAX ou MIN (contrôles 2020, 2023 et 2025, principales 2020, 2023 et 2025), parfois restreinte au même sous-ensemble (principale 2023 : durée minimale pour une maladie donnée) ; comparaison à une moyenne (contrôle 2024) ; HAVING sur un total, un nombre ou une dernière date (contrôle 2018, principales 2023, 2024 et 2025, contrôle 2025) ; NOT IN (principale 2025 ; « qui n'ont jamais participé » en principale 2026) ; filtres par année, mois ou saison (contrôle 2025 : été 2023) ; LIKE avec % (contrôles 2015 et 2023).

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

1 Drill BD-F.1 — « pour chaque » : GROUP BY sur toutes les colonnes affichées
Entraînement 01 / 06

Drill BD-F.1 — « pour chaque » : GROUP BY sur toutes les colonnes affichées

7 questionsCorrigé masqué

Un lycée gère la vie scolaire avec la base suivante (clés primaires soulignées, clés étrangères suivies de #) :

  • Classe ( codeClasse , libClasse , niveau )
  • Eleve ( numEleve , nomEleve , dateNaiss , codeClasse# )
  • Absence ( numEleve# , dateAbs , nbHeures )

niveau vaut « 3e » ou « 4e » ; nbHeures est le nombre d'heures d'absence d'un élève à une date donnée.

  1. Écrire la requête SQL qui affiche, pour chaque classe, son code, son libellé et le nombre de ses élèves.
  2. Écrire la requête SQL qui affiche, pour chaque élève de la classe de code « 4SI1 » ayant au moins une absence, son numéro, son nom et le total de ses heures d'absence.
  3. Écrire la requête SQL qui affiche le nombre d'élèves de chaque niveau.
  4. Un élève propose pour la question 1 la requête R ci-dessous. Expliquer pourquoi elle ne répond pas à la question.

Requête R :

SELECT C.codeClasse, libClasse,
       COUNT(numEleve)
FROM Classe C, Eleve E
WHERE C.codeClasse = E.codeClasse;
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : « pour chaque classe » : un groupe par classe ; codeClasse et libClasse sont affichés sans agrégat, ils sont donc tous les deux dans le GROUP BY.

SELECT C.codeClasse, libClasse,
       COUNT(numEleve) AS nbEleves
FROM Classe C, Eleve E
WHERE C.codeClasse = E.codeClasse
GROUP BY C.codeClasse, libClasse;

codeClasse existe dans les deux tables : il faut le préfixer (C.codeClasse), sinon la colonne est ambiguë.

2. Idée : la classe filtre chaque ligne (WHERE) ; le total est une somme par élève.

SELECT E.numEleve, nomEleve,
       SUM(nbHeures) AS totalHeures
FROM Eleve E, Absence A
WHERE E.numEleve = A.numEleve
  AND codeClasse = '4SI1'
GROUP BY E.numEleve, nomEleve;

La jointure Eleve–Absence ne garde que les élèves qui ont au moins une absence, comme le demande la question.

3. Idée : seule la colonne niveau est affichée sans agrégat : c'est elle seule qui forme les groupes.

SELECT niveau, COUNT(numEleve) AS nbEleves
FROM Classe C, Eleve E
WHERE C.codeClasse = E.codeClasse
GROUP BY niveau;

4. Idée : sans GROUP BY, une fonction d'agrégat résume toutes les lignes en une seule. R compte les élèves de toutes les classes : elle ne rend qu'une ligne, le nombre total d'élèves, accompagné d'un code et d'un libellé de classe sans rapport avec ce total ; MySQL, avec le mode ONLY_FULL_GROUP_BY activé par défaut depuis la version 5.7, la refuse même. Il manque GROUP BY C.codeClasse, libClasse.

2 Drill BD-F.2 — condition sur un nombre ou une dernière date : HAVING, pas WHERE
Entraînement 02 / 06

Drill BD-F.2 — condition sur un nombre ou une dernière date : HAVING, pas WHERE

7 questionsCorrigé masqué

Une agence de location de voitures utilise la base suivante :

  • Agence ( idAgence , nomAgence , ville )
  • Voiture ( immat , marque , idAgence# )
  • Location ( numLoc , dateLoc , nbJours , montant , immat# )
  1. Pour chaque voiture, afficher l'immatriculation, la marque et le nombre de locations effectuées en 2025.
  2. Quelles sont les voitures louées au moins cinq fois en 2025 ? On affichera l'immatriculation et le nombre de locations.
  3. Quelles sont les voitures dont la dernière location a eu lieu avant le 1er janvier 2026 ? On affichera l'immatriculation, la marque et la date de cette dernière location.
  4. La requête R ci-dessous, proposée pour la question 2, est refusée par le SGBD. Pourquoi ?

Requête R :

SELECT immat, COUNT(numLoc)
FROM Location
WHERE YEAR(dateLoc) = 2025
  AND COUNT(numLoc) >= 5
GROUP BY immat;
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : l'année 2025 concerne chaque location : c'est un filtre de lignes, écrit dans WHERE avant le regroupement.

SELECT V.immat, marque,
       COUNT(numLoc) AS nbLocations
FROM Voiture V, Location L
WHERE V.immat = L.immat
  AND YEAR(dateLoc) = 2025
GROUP BY V.immat, marque;

La jointure ne garde que les voitures ayant au moins une location en 2025 : une voiture non louée cette année-là n'apparaît pas.

2. Idée : « au moins cinq fois » porte sur le nombre de locations d'un groupe : ce nombre n'existe qu'après le regroupement, d'où HAVING.

SELECT V.immat, COUNT(numLoc) AS nbLocations
FROM Voiture V, Location L
WHERE V.immat = L.immat
  AND YEAR(dateLoc) = 2025
GROUP BY V.immat
HAVING COUNT(numLoc) >= 5;

3. Idée : « la dernière location » d'une voiture est MAX(dateLoc) de son groupe ; la condition porte sur ce maximum.

SELECT V.immat, marque,
       MAX(dateLoc) AS derniereLocation
FROM Voiture V, Location L
WHERE V.immat = L.immat
GROUP BY V.immat, marque
HAVING MAX(dateLoc) < '2026-01-01';

Écrire WHERE dateLoc < '2026-01-01' changerait la question : on obtiendrait toutes les voitures ayant au moins une location antérieure à 2026, même celles relouées en 2026.

4. WHERE est évalué ligne par ligne, avant la formation des groupes : COUNT(numLoc) n'y a pas encore de valeur. La condition sur le nombre de locations passe dans HAVING, après GROUP BY (question 2).

3 Drill BD-F.3 — « le meilleur » : sous-requête MIN restreinte au même sous-ensemble
Entraînement 03 / 06

Drill BD-F.3 — « le meilleur » : sous-requête MIN restreinte au même sous-ensemble

6 questionsCorrigé masqué

Une fédération de natation enregistre les résultats d'un meeting (temps en secondes) :

  • Nageur ( idNag , nomNag , club )
  • Epreuve ( codeEp , libEp , distance )
  • Resultat ( idNag# , codeEp# , temps )

Extraits des tables :

codeEplibEpdistance
E1100 m papillon100
E250 m nage libre50
idNagnomNagclub
N1Ahmed AyedCS Sfaxien
N2Yosr Ben AliClub Africain
N3Omar HfaiedhEspérance ST
N4Lina MasmoudiCS Sfaxien
idNagcodeEptemps
N1E158.42
N2E157.90
N3E157.90
N4E159.10
N1E224.85
N3E223.96
  1. Écrire la requête SQL qui affiche le nom, le club et le temps des nageurs ayant réalisé le meilleur temps (le plus petit) dans l'épreuve « 100 m papillon ».
  2. Donner le résultat de cette requête sur les extraits ci-dessus.
  3. Un élève a écrit la requête R ci-dessous. Donner son résultat sur les extraits et expliquer l'erreur.

Requête R :

SELECT nomNag, club, temps
FROM Nageur N, Resultat R, Epreuve E
WHERE N.idNag = R.idNag
  AND R.codeEp = E.codeEp
  AND libEp = '100 m papillon'
  AND temps = (SELECT MIN(temps)
               FROM Resultat);
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : « le meilleur temps » est MIN(temps), mais ce minimum doit être calculé dans la même épreuve : la sous-requête reprend la jointure et le filtre sur le libellé.

SELECT nomNag, club, temps
FROM Nageur N, Resultat R, Epreuve E
WHERE N.idNag = R.idNag
  AND R.codeEp = E.codeEp
  AND libEp = '100 m papillon'
  AND temps = (
      SELECT MIN(temps)
      FROM Resultat R2, Epreuve E2
      WHERE R2.codeEp = E2.codeEp
        AND libEp = '100 m papillon');

2. Le plus petit temps du 100 m papillon est 57,90 s\boxed{57{,}90\text{ s}}, réalisé par deux nageurs : la requête affiche deux lignes, (Yosr Ben Ali, Club Africain, 57.90) et (Omar Hfaiedh, Espérance ST, 57.90). La comparaison à une sous-requête garde naturellement les ex æquo.

3. La sous-requête de R calcule le minimum de toute la table Resultat, soit 23,96 s, un temps du 50 m nage libre. Aucun temps du 100 m papillon n'est égal à 23,96 s : R n'affiche aucune ligne. Le filtre sur l'épreuve doit être répété dans la sous-requête.

4 Drill BD-F.4 — « qui n'ont jamais » : NOT IN, et pourquoi une jointure avec <> échoue
Entraînement 04 / 06

Drill BD-F.4 — « qui n'ont jamais » : NOT IN, et pourquoi une jointure avec <> échoue

3 questionsCorrigé masqué

Un cinéma gère sa programmation avec les tables Film ( codeFilm , titre , genre ) et Seance ( numSeance , dateSeance , salle , codeFilm# ). Extraits :

codeFilmtitregenre
F10Le PuitsDrame
F11Sables dorésComédie
F12OrbiteScience-fiction
F13La MédinaDocumentaire
numSeancedateSeancesallecodeFilm
S12026-04-03Salle 1F10
S22026-04-03Salle 2F12
S32026-04-17Salle 1F10
S42026-03-28Salle 2F11
  1. Écrire la requête SQL qui affiche le code et le titre des films qui n'ont été programmés dans aucune séance au cours du mois d'avril 2026.
  2. Donner le résultat de cette requête sur les extraits.
  3. Donner le résultat de la requête R ci-dessous sur les extraits et expliquer pourquoi elle ne répond pas à la question 1.

Requête R :

SELECT DISTINCT titre
FROM Film F, Seance S
WHERE F.codeFilm <> S.codeFilm
  AND dateSeance BETWEEN '2026-04-01'
                     AND '2026-04-30';
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : « aucune séance » : on liste d'abord les films programmés en avril 2026 (sous-requête), puis on garde ceux qui n'y figurent pas.

SELECT codeFilm, titre
FROM Film
WHERE codeFilm NOT IN (
    SELECT codeFilm FROM Seance
    WHERE dateSeance BETWEEN '2026-04-01'
                         AND '2026-04-30');

2. Films programmés en avril 2026 : F10 (séances S1 et S3) et F12 (séance S2) ; la séance S4 de F11 date du 28 mars. Résultat : (F11, Sables dorés) et (F13, La Médina).

3. R associe chaque film à chaque séance d'avril d'un autre film : Le Puits est associé à S2, Orbite à S1 et S3, Sables dorés et La Médina aux trois séances. Les quatre titres sont donc affichés : Le Puits, Sables dorés, Orbite, La Médina. R répond à « films pour lesquels il existe une séance d'avril d'un autre film », pas à « films sans séance en avril ».

5 Drill BD-F.5 — chaîne de jointures à travers des tables dont rien n'est affiché
Entraînement 05 / 06

Drill BD-F.5 — chaîne de jointures à travers des tables dont rien n'est affiché

7 questionsCorrigé masqué

Un festival de musique gère sa billetterie :

  • Pays ( codePays , nomPays )
  • Artiste ( idArt , nomArt , codePays# )
  • Concert ( numConc , dateConc , scene , idArt# )
  • Billet ( numBillet , categorie , prix , numConc# )
  1. Quels sont les billets vendus pour les concerts d'artistes originaires du « Sénégal » ? On affichera les champs numBillet, categorie et prix.
  2. Quelle est la recette (somme des prix des billets) de chaque pays d'origine des artistes ? On affichera le nom du pays et la recette.
  3. Dans la requête de la question 1, aucune colonne des tables Concert et Artiste n'est affichée. Pourquoi ces tables sont-elles indispensables ? Que se passe-t-il si l'on oublie la condition de jointure entre Concert et Artiste ?
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : le prix est dans Billet, le pays dans Pays, et ces tables n'ont aucune colonne commune : on suit la chaîne des clés étrangères Billet → Concert → Artiste → Pays.

SELECT numBillet, categorie, prix
FROM Billet B, Concert C, Artiste A, Pays P
WHERE B.numConc = C.numConc
  AND C.idArt = A.idArt
  AND A.codePays = P.codePays
  AND nomPays = 'Sénégal';

2. Idée : même chaîne de jointures, puis un groupe par pays.

SELECT nomPays, SUM(prix) AS recette
FROM Billet B, Concert C, Artiste A, Pays P
WHERE B.numConc = C.numConc
  AND C.idArt = A.idArt
  AND A.codePays = P.codePays
GROUP BY nomPays;

3. Concert et Artiste portent les maillons de la chaîne : numConc relie un billet à son concert, idArt relie le concert à son artiste, codePays relie l'artiste à son pays. Sans la condition C.idArt = A.idArt, le concert n'est plus rattaché à son artiste : chaque billet, quel que soit son concert, est combiné avec chaque artiste sénégalais. Le résultat contient alors des billets de concerts d'artistes d'autres pays, répétés autant de fois qu'il y a d'artistes sénégalais.

6 Drill BD-F.6 — LIKE : '%' et '_' ; = ne connaît pas les jokers
Entraînement 06 / 06

Drill BD-F.6 — LIKE : '%' et '_' ; = ne connaît pas les jokers

2 questionsCorrigé masqué

Le parc informatique d'un lycée est décrit par la table Poste ( numPoste , refPoste , salle , systeme ). Extrait :

numPosterefPostesallesysteme
1PC-A13Labo 1Linux
2PC-B03Labo 2Windows
3SRV-01Salle serveursLinux
4PC-A31Labo 1Windows
5IMP-3CDIAucun
6PC-B07Labo 2Linux
  1. Donner les valeurs de refPoste affichées par la requête SELECT refPoste FROM Poste WHERE … lorsque la condition est :
    1. refPoste LIKE 'PC%'
    2. refPoste LIKE '%3'
    3. refPoste LIKE '%3%'
    4. refPoste LIKE '___-%'
    5. refPoste = 'PC%'
  2. Écrire la requête SQL qui affiche numPoste, refPoste et salle des postes installés dans une salle dont le nom contient « Labo » et fonctionnant sous « Linux ».
Voir la correction commentéeAprès avoir posé votre démarche

1. Idée : avec LIKE, % remplace une suite quelconque de caractères (éventuellement vide) et _ exactement un caractère ; avec =, % n'est qu'un caractère ordinaire.

  • a. commence par « PC » : PC-A13, PC-B03, PC-A31, PC-B07.
  • b. se termine par « 3 » : PC-A13, PC-B03, IMP-3.
  • c. contient un « 3 » : PC-A13, PC-B03, PC-A31, IMP-3.
  • d. trois caractères puis un tiret en 4e position : SRV-01, IMP-3 (dans « PC-… » le tiret est en 3e position).
  • e. aucune ligne : aucune référence n'est égale à la chaîne « PC% ».

2. Idée : « contient » s'écrit avec % des deux côtés ; le système est une égalité simple.

SELECT numPoste, refPoste, salle
FROM Poste
WHERE salle LIKE '%Labo%'
  AND systeme = 'Linux';

Sur l'extrait : (1, PC-A13, Labo 1) et (6, PC-B07, Labo 2).

Relier ce raisonnement au bac

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