Exercice 2 : Jointures et requêtes complexes
Concours Blanc - Correction détaillée : Bases de données SQL
Section titled “Concours Blanc - Correction détaillée : Bases de données SQL”Filière : BCPST
Matière : Informatique
Thème : Jointures et requêtes complexes
Introduction et Présentation du Modèle
Section titled “Introduction et Présentation du Modèle”Dans le cadre de la gestion d’un réseau de parcs zoologiques, on souhaite concevoir une base de données relationnelle permettant de suivre les animaux, leurs enclos, ainsi que les soigneurs attitrés.
La base de données est constituée de trois relations (tables) dont les schémas relationnels et les types de données sont décrits ci-dessous :
-
Enclos(gestion des zones géographiques) :id_enclos(INT, Clé Primaire) : Identifiant unique de l’enclos.nom_enclos(VARCHAR) : Nom usuel de la zone (ex: ).superficie(, ) : Superficie de l’enclos.
-
Soigneur(gestion du personnel) :id_soigneur(INT, Clé Primaire) : Identifiant unique du soigneur.nom(VARCHAR) : Nom du soigneur.specialite(VARCHAR) : Domaine d’expertise (ex: ).
-
Animal(gestion de la faune) :id_animal(INT, Clé Primaire) : Identifiant unique de l’animal.nom_animal(VARCHAR) : Nom de l’animal.espece(VARCHAR) : Espèce biologique (ex: ).regime(VARCHAR) : Régime alimentaire (, , $\text{“Omnivore”`}).id_enclos(INT, Clé Étrangère référençantEnclos(id_enclos)) : Enclos où réside l’animal.id_soigneur(INT, Clé Étrangère référençantSoigneur(id_soigneur)) : Soigneur référent de l’animal.
Problème Guidé : Pas à pas
Section titled “Problème Guidé : Pas à pas”Partie 1 : Requêtes de sélection simple et filtrage
Section titled “Partie 1 : Requêtes de sélection simple et filtrage”Question 1.1
Section titled “Question 1.1”Énoncé : Écrire une requête SQL permettant d’afficher les noms et espèces de tous les animaux dont le régime alimentaire est strictement .
Correction pas à pas :
- On cible la table contenant ces informations :
Animal. - On sélectionne les attributs d’intérêt :
nom_animal,espece. - On filtre les lignes selon la condition
regime = 'Carnivore'.
SELECT nom_animal, especeFROM AnimalWHERE regime = 'Carnivore';Partie 2 : Jointures internes (INNER JOIN)
Section titled “Partie 2 : Jointures internes (INNER JOIN)”Question 2.1
Section titled “Question 2.1”Énoncé : Afficher le nom de chaque animal ainsi que le nom de l’enclos dans lequel il vit.
Correction pas à pas :
- Les données sont réparties dans deux tables :
Animal(pour le nom de l’animal) etEnclos(pour le nom de l’enclos). - La liaison entre ces deux tables s’effectue via la clé étrangère
id_enclosprésente dans la tableAnimal. - On utilise une jointure interne (
JOINouINNER JOIN).
SELECT Animal.nom_animal, Enclos.nom_enclosFROM AnimalINNER JOIN Enclos ON Animal.id_enclos = Enclos.id_enclos;Partie 3 : Jointures multiples et agrégation
Section titled “Partie 3 : Jointures multiples et agrégation”Question 3.1
Section titled “Question 3.1”Énoncé : Pour chaque soigneur (afficher son nom), compter le nombre d’animaux dont il a la charge. On veillera à afficher aussi les soigneurs ne s’occupant d’aucun animal.
Correction pas à pas :
- On a besoin de la table
Soigneuret de la tableAnimal. - Pour inclure les soigneurs n’ayant aucun animal assigné, une jointure interne ne suffit pas (elle éliminerait les comptes à ). Il faut utiliser une jointure externe (
LEFT JOINen partant de la tableSoigneur). - On groupe les résultats par soigneur et on utilise la fonction d’agrégation
COUNT.
SELECT Soigneur.nom, COUNT(Animal.id_animal) AS nombre_animauxFROM SoigneurLEFT JOIN Animal ON Soigneur.id_soigneur = Animal.id_soigneurGROUP BY Soigneur.id_soigneur, Soigneur.nom;Partie 4 : Requêtes imbriquées complexes
Section titled “Partie 4 : Requêtes imbriquées complexes”Question 4.1
Section titled “Question 4.1”Énoncé : Afficher les caractéristiques des animaux (nom, espèce) qui résident dans un enclos dont la superficie est strictement supérieure à la superficie moyenne de tous les enclos de la base.
Correction pas à pas :
- Étape 1 : Calculer la superficie moyenne des enclos.
SELECT AVG(superficie) FROM Enclos
- Étape 2 : Identifier les enclos dont la superficie dépasse cette moyenne.
- Étape 3 : Joindre la table
Animalà ces enclos pour récupérer les animaux correspondants.
SELECT A.nom_animal, A.especeFROM Animal AJOIN Enclos E ON A.id_enclos = E.id_enclosWHERE E.superficie > ( SELECT AVG(superficie) FROM Enclos);Analyse critique des résultats et Bonnes Pratiques (Attendu Concours)
Section titled “Analyse critique des résultats et Bonnes Pratiques (Attendu Concours)”-
Performance des jointures : L’utilisation de clés étrangères implique la création quasi-systématique d’index sur ces colonnes par le SGBD. Lors de requêtes impliquant des tables de grande taille (plus de lignes, fréquent en modélisation biologique ou écologiques), l’oubli d’index sur les attributs de liaison (
id_enclos,id_soigneur) conduit à des complexités algorithmiques en au lieu de avec des index (arbres B+). -
Gestion des valeurs NULL (Piège classique) : Dans la question 3.1, l’utilisation d’un
LEFT JOINest cruciale. Si un candidat utilise unINNER JOIN, le soigneur sans animal disparaît purement et simplement du résultat. De plus, lors de l’utilisation deCOUNT(Animal.id_animal), le SGBD compte correctement pour les valeursNULLassociées, alors queCOUNT(*)renverrait erronément (en comptant la ligne de jointure avec desNULL). -
Robustesse des requêtes imbriquées : La sous-requête de la question 4.1 (
SELECT AVG(superficie)...) renvoie une unique valeur scalaire. Elle est donc compatible avec l’opérateur de comparaison strict>. Si elle avait pu renvoyer plusieurs lignes, il aurait fallu utiliser l’opérateur> ANYou> ALL. C’est un point de vigilance particulièrement évalué à l’oral et à l’écrit en BCPST.