Retour à la liste des articles Articles
7 minutes de lecture

Qu'est-ce qu'une requête imbriquée en SQL ?

Avez-vous déjà souhaité pouvoir construire une requête avec plusieurs instructions SELECT ? Bonne nouvelle ! Vous pouvez le faire - et bien plus encore - avec les requêtes imbriquées de SQL.

Si vous apprenez SQL (et que vous écrivez des requêtes) depuis un certain temps, vous avez probablement rencontré des cas où il semble que vous ayez besoin d'une autre instruction SELECT dans votre instruction principale. Vous vous demandez peut-être "Est-il possible d'utiliser des instructions SELECT imbriquées en SQL ? Oui, c'est possible ! Dans cet article, je vais expliquer la requête imbriquée (alias le SELECT imbriqué) et comment l'utiliser efficacement.

Si vous voulez pratiquer le SQL, consultez notre contenu sur La pratique du SQL qui propose plusieurs cours pratiques et interactifs sur le langage SQL, avec des exercices couvrant les instructions SELECT imbriquées et d'autres fonctionnalités SQL complexes.

Qu'est-ce qu'un SELECT imbriqué ?

Un SELECT imbriqué est une requête dans une requête, c'est-à-dire que vous avez une instruction SELECT dans le SELECT principal. Pour rendre le concept plus clair, prenons ensemble un exemple.

Dans cet article, nous allons travailler avec les données d'un lycée fictif. La base de données comprend trois tables : students, teachers, et classes. Vous pouvez voir les tables ci-dessous :

Students

idnameclass_idGPA
1Jack Black33.45
2Daniel White13.15
3Kathrine Star13.85
4Helen Bright23.10
5Steve May22.40

Teachers

idnamesubjectclass_idmonthly_salary
1Elisabeth GreyHistory32,500
2Robert SunLiterature[NULL]2,000
3John ChurchillEnglish12,350
4Sara ParkerMath23,000

Classes

idgradeteacher_idnumber_of_students
110321
211425
312128

Supposons que vous souhaitiez trouver tous les étudiants qui ont une moyenne supérieure à la moyenne. Cependant, vous ne connaissez pas la moyenne des notes obtenues. Bien sûr, vous pouvez utiliser une requête pour le découvrir :

SELECT AVG(GPA)
FROM students;

Vous obtiendrez un nombre (3,19) que vous pourrez utiliser pour résoudre la tâche initiale - afficher toutes les informations relatives aux étudiants ayant une moyenne supérieure à cette moyenne :

SELECT *
FROM students
WHERE GPA > 3.19;

Mais pouvez-vous résoudre cette tâche en une seule étape ? Vous le pouvez avec une requête imbriquée. Voici à quoi cela ressemble :

SELECT *
FROM students
WHERE GPA > (
	SELECT AVG(GPA)
	FROM students);

Notre sous-requête renvoie une seule valeur (c'est-à-dire une table avec une seule colonne et une seule ligne). C'est important pour que l'opérateur de comparaison fonctionne. Avec la note moyenne de GPA renvoyée par la requête interne, la requête externe peut sélectionner les étudiants qui satisfont à notre condition de filtre (c'est-à-dire une note de GPA supérieure à la moyenne).

Et voici le résultat :

idnameclass_idGPA
1Jack Black33.45
3Kathrine Star13.85

Le terme approprié pour cette instruction SELECT imbriquée est une sous-requête. Il existe de nombreux scénarios dans lesquels les sous-requêtes SQL sont très utiles.

Autres exemples de requêtes SQL imbriquées

Tout d'abord, vous pouvez placer un SELECT imbriqué dans la clause WHERE avec des opérateurs de comparaison ou les opérateurs IN, NOT IN, ANY ou ALL. Le deuxième groupe d'opérateurs est utilisé lorsque votre sous-requête renvoie une liste de valeurs (plutôt qu'une valeur unique, comme dans l'exemple précédent) :

  • L'opérateur IN vérifie si une certaine valeur se trouve dans la table renvoyée par la sous-requête.
  • L'opérateur NOT IN élimine par filtrage les lignes correspondant aux valeurs non présentes dans la table renvoyée par la sous-requête.
  • L'opérateur ANY est utilisé avec des opérateurs de comparaison pour évaluer si l'une des valeurs renvoyées par la sous-requête satisfait à la condition.
  • L'opérateur ALL est également utilisé avec des opérateurs de comparaison pour évaluer si toutes les valeurs renvoyées par la sous-requête satisfont à la condition.

Voyons comment fonctionne l'opérateur IN. Dans cet exemple, vous allez calculer le nombre moyen d'élèves dans les classes où le professeur enseigne l'histoire ou l'anglais :

SELECT AVG(number_of_students)
FROM classes
WHERE teacher_id IN (
	SELECT id
	FROM teachers
	WHERE subject = 'English' OR subject = 'History');

Ici, vous utilisez une sous-requête pour sélectionner uniquement les ID des enseignants qui correspondent à des enseignants d'anglais ou d'histoire. Notez que notre sous-requête renvoie une liste de valeurs, c'est-à-dire une table avec une colonne (id) et plusieurs lignes qui satisfont la condition de la requête interne.

Ensuite, dans notre requête externe, nous calculons le nombre moyen d'élèves uniquement pour les classes qui satisfont à la condition ci-dessus. Pour chaque identifiant d'enseignant, l'opérateur IN vérifie que cet identifiant est présent dans la table renvoyée par la requête interne ; cela garantit que seules les classes correspondant à ces enseignants sont prises en compte dans le calcul.

Si vous souhaitez obtenir d'autres exemples d'utilisation des opérateurs IN, NOT IN, ANY ou ALL, consultez notre guide sur les sous-requêtes SQL.

Plusieurs sous-requêtes dans une seule instruction

Vous êtes prêt pour des exemples plus difficiles ? En fait, il est possible d'avoir plusieurs SELECT imbriqués dans une seule instruction.

Supposons que vous souhaitiez afficher toutes les informations concernant les élèves de la classe ayant le plus grand nombre d'élèves. Pour répondre à cette question, vous devrez trouver la classe ayant le nombre maximal d'élèves, puis définir cette classe. Enfin, vous devez afficher les informations relatives aux élèves de cette classe.

Vous pouvez utiliser une sous-requête dans une autre sous-requête pour répondre à cette question :

SELECT *
FROM students
WHERE class_id = (
	SELECT id
	FROM classes
	WHERE number_of_students = (
		SELECT MAX(number_of_students)
		FROM classes));

Plutôt pratique, n'est-ce pas ?

Utilisation de sous-requêtes en dehors de WHERE

En outre, les sous-requêtes ne sont pas limitées à une utilisation dans la clause WHERE. Par exemple, vous pouvez également utiliser une requête imbriquée dans la clause FROM. Dans l'exemple suivant, notre sous-requête ne renvoie pas une valeur unique, mais un tableau.

Cherchons à savoir quel domaine correspond au salaire moyen le plus élevé des enseignants. Vous devrez d'abord calculer le salaire moyen par matière, puis utiliser ce tableau pour trouver le salaire moyen maximum :

SELECT subject, MAX(salary_by_subject.avg_salary) AS max_salary
FROM (
	SELECT subject, AVG(monthly_salary) AS avg_salary
	FROM teachers
	GROUP BY subject) salary_by_subject;

Notez que la requête interne renverra un tableau avec plusieurs lignes et colonnes. Pour être plus précis, le tableau aura deux colonnes, subject et avg_salary, pour montrer le salaire moyen des enseignants en fonction de leur matière principale. Le nombre de lignes correspondra au nombre de matières uniques enseignées dans l'école (c'est-à-dire tel que spécifié dans la table teachers table). Vous devez également spécifier un alias pour cette table : -. salary_by_subject.

Ensuite, la requête externe calcule simplement le salaire moyen maximum sur la base de la table salary_by_subject et renvoie cette valeur, ainsi que le nom de la matière correspondante :

subjectmax_salary
Math3,000

Comme vous pouvez le constater, les professeurs de mathématiques de notre école ont le salaire mensuel moyen le plus élevé (3 000 $).

Pour certaines tâches, vous pouvez avoir besoin que la requête interne utilise les informations de la requête externe. Lorsque deux requêtes sont liées de cette manière, on parle de sous-requêtes corrélées. Il s'agit d'un sujet plus avancé qui est très bien expliqué dans notre guide des sous-requêtes corrélées pour les débutants et dans ce tutoriel pratique sur la rédaction de sous-requêtes corrélées.

Conseils supplémentaires sur l'utilisation des SELECT imbriqués

Les sous-requêtes SQL sont un outil puissant. Elles nous permettent d'effectuer des tâches plus efficacement en n'ayant qu'une seule requête au lieu de plusieurs.

Lorsque vous utilisez des requêtes imbriquées, gardez ces considérations à l'esprit :

  • Les sous-requêtes peuvent renvoyer des valeurs uniques ou des tableaux (avec une ou plusieurs lignes et colonnes).
  • Vous pouvez inclure une sous-requête :
    • Dans la clause WHERE, pour filtrer les données.
    • Dans la clause FROM, pour spécifier une nouvelle table.
    • Dans la clause SELECT, pour spécifier une certaine colonne.
    • Dans la clause HAVING, comme sélecteur de groupe.
  • Les sous-requêtes doivent toujours être placées entre parenthèses ().
  • Les différents systèmes de gestion de bases de données ont certaines limitations quant au nombre de niveaux de sous-requêtes (par exemple, jusqu'à 32 niveaux dans SQL Server). Cependant, en pratique, vous aurez rarement plus de 2 ou 3 niveaux de requêtes imbriquées.
  • Les sous-requêtes sont souvent inefficaces sur le plan du calcul. Je recommande donc d'éviter les requêtes imbriquées lorsque d'autres options sont disponibles (par exemple, les JOIN).

Il est temps de pratiquer les sous-requêtes SQL !

Maintenant, que vous avez beaucoup appris sur les requêtes imbriquées en SQL, vous êtes probablement impatient de commencer à les mettre en pratique ! Heureusement, nous disposons de BEAUCOUP d'exercices interactifs pour vous permettre de pratiquer différentes sous-requêtes SQL.

Tout d'abord, notre cours SQL pour les débutants comporte une grande section sur les sous-requêtes. Ne manquez pas de la consulter !

Si vous voulez devenir un utilisateur vraiment confiant des requêtes imbriquées en SQL, je vous recommande également de suivre notre cours sur La pratique du SQL. Elle contient des cours de SQL interactifs avec des exercices pratiques pour vous exercer aux sous-requêtes et d'autres constructions difficiles en SQL.

Les sous-requêtes feront définitivement de vous un utilisateur de SQL beaucoup plus puissant. Bon apprentissage !