Imagine que tu bosses comme analyste dans une université (on fait bien une base de données pour une université, tu te souviens ?). On t'a demandé de ne pas juste afficher les étudiants et leurs notes, mais d'ajouter une colonne avec la note maximale du groupe, pour comparer facilement les résultats. Comment faire ça ? Bien sûr, avec des sous-requêtes dans le SELECT !
Une sous-requête dans le SELECT te permet de calculer des valeurs directement pendant l'exécution de la requête principale. C'est cool, parce que tu peux combiner des calculs agrégés, des filtres complexes et même d'autres collections de données dans une seule requête.
Bases des requêtes imbriquées dans SELECT
Une sous-requête dans le SELECT fonctionne littéralement comme ça sonne : tu insères le résultat d'un SELECT dans un autre. Ça permet de calculer des valeurs supplémentaires pour chaque ligne du résultat.
Voici un exemple simple. Disons qu'on a une table students avec la structure suivante :
| student_id | name | group_id |
|---|---|---|
| 1 | Linda | 101 |
| 2 | Otto | 102 |
| 3 | Anna | 101 |
Et une table grades :
| grade_id | student_id | grade |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 3 | 5 |
| 5 | 3 | 4 |
Exemple 1 : Ajouter la note maximale du groupe
Objectif : afficher les noms des étudiants, leurs notes et la note maximale du groupe, pour voir à quel point les notes de chaque étudiant diffèrent des meilleurs résultats du groupe.
Code SQL :
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT MAX(grade) -- cette requête retourne une seule valeur
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS max_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Ce qui se passe ici :
- Pour chaque étudiant, on récupère son nom et sa note (
s.name,g.grade). SELECT MAX(grade)— c'est la sous-requête qui retourne la note maximale dans le groupe de l'étudiant.- La sous-requête s'exécute pour chaque ligne de la requête principale et utilise la condition
WHERE students.group_id = s.group_idpour limiter la sélection à un seul groupe.
Exemple 2 : Moyenne des notes du groupe
Tu veux être encore plus utile pour les analystes ? Ajoutons à l'affichage non seulement la note maximale, mais aussi la moyenne des notes du groupe.
Code SQL :
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT AVG(grade)
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS avg_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Maintenant :
- Au lieu de
MAX()on utiliseAVG()pour calculer la moyenne du groupe. - On obtient une analyse "live" des données.
Limites et recommandations
Les sous-requêtes dans le SELECT sont puissantes, mais il faut les utiliser avec précaution :
- Performance. Chaque sous-requête s'exécute pour chaque ligne de la requête principale. Ça peut ralentir l'exécution de la requête SQL si les tables sont grosses. Par exemple, s'il y a 1000 étudiants, la sous-requête s'exécutera 1000 fois !
- Indexes. Pour accélérer ce genre de requêtes, il est important d'indexer correctement les colonnes utilisées dans les conditions
WHEREde la sous-requête. - Lisibilité. Essaie d'éviter trop d'imbrication. Si les sous-requêtes deviennent trop complexes, pense à les déplacer dans le
FROMou à créer des tables temporaires.
Exemples d'utilisation
Regardons encore quelques cas sympas.
Exemple 3 : Nombre de cours pour chaque étudiant
On affiche un tableau où, pour chaque étudiant, on montre combien de cours il a choisis. La table enrollments est liée aux étudiants par student_id :
| student_id | course_id |
|---|---|
| 1 | 201 |
| 1 | 202 |
| 2 | 201 |
| 3 | 203 |
Code SQL :
SELECT
s.name AS student_name,
(
SELECT COUNT(*)
FROM enrollments
WHERE enrollments.student_id = s.student_id
) AS course_count
FROM
students s;
Ici, la sous-requête compte le nombre d'enregistrements dans la table enrollments pour chaque étudiant.
Exemple 4 : Flag "excellent" pour chaque étudiant
On va montrer si un étudiant est "excellent". Disons que le critère pour être excellent — c'est d'avoir toutes ses notes à 5.
Code SQL :
SELECT
s.name AS student_name,
(
SELECT CASE
WHEN MIN(g.grade) = 5 THEN 'Excellent'
ELSE 'Pas excellent'
END
FROM grades g
WHERE g.student_id = s.student_id
) AS status
FROM
students s;
Ici, on utilise un CASE imbriqué pour donner le statut "Excellent" seulement aux étudiants qui ont toutes leurs notes à 5.
Optimisation des sous-requêtes dans SELECT
On a déjà dit que la performance peut devenir un souci. Voilà quelques conseils pour l'améliorer :
- Utilise les indexes. Si les sous-requêtes filtrent des données, assure-toi que les colonnes utilisées sont bien indexées.
- Mets en cache les résultats. Parfois, ça vaut le coup de sortir les sous-requêtes dans des vues (
VIEW) ou des tables temporaires. - Moins d'imbrication. Abuse pas de l'imbrication si tu peux faire plus simple.
Les sous-requêtes dans le SELECT ouvrent plein de possibilités pour les calculs et l'analyse de données. Même si elles peuvent être gourmandes en ressources, bien optimisées elles rendent SQL beaucoup plus expressif et flexible. Donc n'hésite pas à expérimenter et à trouver tes propres façons d'améliorer tes requêtes !
GO TO FULL VERSION