CodeGym /Cours /SQL SELF /Utiliser SELECT à l'intérieur d'un S...

Utiliser SELECT à l'intérieur d'un SELECT

SQL SELF
Niveau 13 , Leçon 1
Disponible

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 :

  1. Pour chaque étudiant, on récupère son nom et sa note (s.name, g.grade).
  2. SELECT MAX(grade) — c'est la sous-requête qui retourne la note maximale dans le groupe de l'étudiant.
  3. 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_id pour 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 utilise AVG() 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 :

  1. 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 !
  2. Indexes. Pour accélérer ce genre de requêtes, il est important d'indexer correctement les colonnes utilisées dans les conditions WHERE de la sous-requête.
  3. Lisibilité. Essaie d'éviter trop d'imbrication. Si les sous-requêtes deviennent trop complexes, pense à les déplacer dans le FROM ou à 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 :

  1. Utilise les indexes. Si les sous-requêtes filtrent des données, assure-toi que les colonnes utilisées sont bien indexées.
  2. 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.
  3. 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 !

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION