Exercice 1 : SQL avancé
Problème Guidé : Analyse et Optimisation de Requêtes en SQL Avancé
Section titled “Problème Guidé : Analyse et Optimisation de Requêtes en SQL Avancé”En tant qu’examinateur en classes préparatoires (filière MPI), j’attends des candidats non seulement une maîtrise syntaxique du SQL, mais aussi une compréhension fine de la sémantique des requêtes complexes (sous-requêtes, agrégations, fonctions de fenêtrage) et de leur complexité algorithmique sous-jacente.
I. Présentation du Schéma Relationnel
Section titled “I. Présentation du Schéma Relationnel”On considère une base de données relationnelle modélisant le système d’information d’une plateforme de commerce en ligne. Le schéma est constitué des trois relations suivantes :
Notes de modélisation :
- Les attributs soulignés désignent les clés primaires.
- Les attributs suivis d’une étoile désignent des clés étrangères référençant les tables correspondantes.
- Le domaine de est , et celui de est .
II. Questions Préliminaires (Extraction et Agrégation)
Section titled “II. Questions Préliminaires (Extraction et Agrégation)”Question 1
Section titled “Question 1”Écrire une requête SQL permettant d’afficher le nom des clients ainsi que le montant total des achats qu’ils ont effectués. On ne souhaite afficher que les clients dont le montant total dépasse .
Corrigé pas à pas :
Section titled “Corrigé pas à pas :”Pour répondre à cette question, il est nécessaire de :
- Joindre les tables et (via ), puis la table (via ) pour accéder au prix unitaire.
- Calculer le montant par ligne de commande ().
- Grouper par client pour sommer ces montants.
- Filtrer les agrégats avec la clause .
SELECT c.nom, SUM(co.quantite * p.prix) AS montant_totalFROM Clients cJOIN Commandes co ON c.id_client = co.id_clientJOIN Produits p ON co.id_produit = p.id_produitGROUP BY c.id_client, c.nomHAVING SUM(co.quantite * p.prix) > 1000.0;III. Problème Principal : Analyse Avancée et Fonctions de Fenêtrage
Section titled “III. Problème Principal : Analyse Avancée et Fonctions de Fenêtrage”Question 2
Section titled “Question 2”On souhaite identifier, pour chaque catégorie de produits, le produit le plus cher. En cas d’égalité de prix, tous les produits concernés doivent être affichés.
Donner une solution n’utilisant pas de fonctions de fenêtrage (approche classique par sous-requête), puis une solution utilisant les fonctions de fenêtrage (recommandée en MPI pour l’optimisation).
Corrigé pas à pas :
Section titled “Corrigé pas à pas :”Méthode 1 : Sous-requête corrélée avec ou L’idée est de sélectionner les produits dont le prix est égal au maximum de leur catégorie.
SELECT p1.nom_produit, p1.categorie, p1.prixFROM Produits p1WHERE p1.prix = ( SELECT MAX(p2.prix) FROM Produits p2 WHERE p2.categorie = p1.categorie );Méthode 2 : Fonctions de fenêtrage ( ou ) L’utilisation de la fonction permet d’attribuer un rang aux produits par catégorie, triés par prix décroissant.
WITH ProduitsClasses AS ( SELECT nom_produit, categorie, prix, RANK() OVER (PARTITION BY categorie ORDER BY prix DESC) as rk FROM Produits)SELECT nom_produit, categorie, prixFROM ProduitsClassesWHERE rk = 1;Question 3
Section titled “Question 3”Écrire une requête SQL qui retourne, pour chaque client ayant effectué au moins une commande, la date de sa première commande et la date de sa dernière commande, ainsi que l’écart en jours entre ces deux commandes.
Corrigé pas à pas :
Section titled “Corrigé pas à pas :”On utilise les fonctions d’agrégation et sur la date de commande. Pour calculer l’écart en jours, la syntaxe dépend légèrement du SGBD (on suppose ici une fonction standard type ou soustraction directe de dates selon le moteur SQL).
SELECT c.nom, MIN(co.date_commande) AS premiere_commande, MAX(co.date_commande) AS derniere_commande, MAX(co.date_commande) - MIN(co.date_commande) AS ecart_joursFROM Clients cJOIN Commandes co ON c.id_client = co.id_clientGROUP BY c.id_client, c.nom;IV. Analyse Critique des Résultats et Complexité
Section titled “IV. Analyse Critique des Résultats et Complexité”En entretien ou à l’écrit de l’épreuve d’informatique MPI, le jury attend un regard critique sur les performances des requêtes proposées.
-
Coût des jointures et indexation :
- Pour la Question 1, la requête effectue une triple jointure. Sans index sur les clés étrangères ( et dans la table ), le SGBD risque d’effectuer des balayages de tables complets (Full Table Scans), menant à une complexité temporelle en où et sont les tailles des tables et .
- La mise en place d’arbres B-Trees sur les clés étrangères réduit cette complexité à via des jointures par index (Index Nested Loop Joins).
-
Comparaison des méthodes de la Question 2 :
- La Méthode 1 (sous-requête corrélée) évalue, pour chaque ligne, le maximum de la catégorie. Si elle est mal optimisée par le planificateur de requêtes, sa complexité peut atteindre (où est le nombre de produits).
- La Méthode 2 (avec et CTE) ne nécessite qu’un tri global ou partiel par partition, ramenant la complexité algorithmique à , ce qui est nettement plus efficace sur de grands volumes de données.