Passer au contenu principal
eLearner.app
Module 4 · Leçon 4 sur 416/57 dans le cours~12 min
Leçons du module (4/4)

Une requête dans une autre : sous-requêtes

Vous avez appris à extraire, filtrer, regrouper, joindre et transformer. Là est une dernière idée fondamentale : mettre une requête dans une autre. Ce sont appelées sous-requêtes et elles constituent l'étape qui vous permet de répondre aux questions comme "qui gagne au-dessus de la moyenne ?" ou "quels départements ont quelqu'un affecté à un projet ?".

La syntaxe de base

Une sous-requête est un SELECT entouré de parenthèses, utilisé à la place d'un seul valeur ou une liste de valeurs dans une autre requête :

SQL
-- Find who earns MORE THAN THE COMPANY AVERAGE:
SELECT first_name, last_name, salary
FROM   employees
WHERE  salary > (SELECT AVG(salary) FROM employees);

Le moteur exécute d'abord la sous-requête - SELECT AVG(salary) FROM employees renvoie un seul numéro - puis utilise ce numéro dans le WHERE externe comme si vous l'aviez écrit à la main. C'est précisément l'avantage : vous faites pas besoin de connaître la moyenne à l’avance, SQL la calcule pour vous.

Les trois "types" les plus courants

1. Sous-requête renvoyant une seule valeur

L'exemple ci-dessus : la sous-requête produit une ligne, une colonne (appelée scalaire). Vous l'utilisez avec =, >, < et ainsi de suite.

SQL
-- Employee with the highest salary:
SELECT first_name, last_name
FROM   employees
WHERE  salary = (SELECT MAX(salary) FROM employees);

2. Sous-requête renvoyant une liste

La sous-requête produit une colonne, plusieurs lignes. Vous l'utilisez avec IN (...) :

SQL
-- Departments that have at least one employee:
SELECT name
FROM   departments
WHERE  id IN (SELECT DISTINCT department_id
              FROM employees
              WHERE department_id IS NOT NULL);

3. Sous-requête en tant que "table" (FROM)

Une sous-requête peut également remplacer une table dans FROM. Il est utile de pré-calculez les agrégats, puis filtrez-les ou joignez-les :

SQL
-- Departments with average salary above 40000:
SELECT d.name, medie.stipendio_medio
FROM   departments AS d
JOIN  (SELECT department_id, AVG(salary) AS stipendio_medio
       FROM employees
       GROUP BY department_id) AS medie
   ON d.id = medie.department_id
WHERE  medie.stipendio_medio > 40000;

Sous-requête ou JOIN ? Quand utiliser lequel

Souvent, le même résultat peut être obtenu avec un JOIN ou avec une sous-requête. Règle générale :

  • Pour filtrer les lignes d'une table en fonction d'une propriété d'une autre ("employés dont les services sont…"), IN (subquery) est très lisible.
  • Pour combiner des colonnes de plusieurs tables dans le résultat, utilisez JOIN.
  • calculer un agrégat et l'utiliser comme seuil (""au-dessus du moyenne"), la sous-requête scalaire est le choix naturel.

En pratique vous verrez les deux : le moteur SQL les optimise souvent de la même manière manière. Choisissez le formulaire qui se lit le mieux.

Essayez-le

Exercice#sql.m4.l4.e1
Tentatives : 0Chargement…

Recherchez le prénom (first_name), le nom (last_name) et le salaire (salaire) des employés qui gagnent STRICTEMENT plus que la moyenne de l'entreprise. Trois colonnes.

Chargement de l'éditeur…
Afficher l'indice

Remplacer ? avec la sous-requête SELECT AVG(salary) FROM employés — elle renvoie un nombre unique à utiliser comme seuil.

Solution disponible après 3 tentatives

Exercice de révision

Exercice#sql.m4.l4.e2
Tentatives : 0Chargement…

Répertoriez le nom (departments.name) des départements qui ont au moins un employé dont le salaire est strictement supérieur à 50 000. Utilisez une sous-requête avec IN. Trier par ordre alphabétique.

Chargement de l'éditeur…
Afficher l'indice

La sous-requête interne renvoie les identifiants des départements qui ont des employés avec un salaire > 50 000. Puis WHERE id IN (...) sur la requête externe.

Solution disponible après 3 tentatives