0Pricing
SQL Academy · Leçon

Sous-requêtes corrélées

Une sous-requête qui dépend de la ligne extérieure.

Sous-requêtes corrélées est une leçon SQL Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage SQL Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours SQL Academy comprend 4 leçons au total.

Qu'est-ce qu'une sous-requête corrélée ?

Une sous-requête corrélée est une sous-requête qui fait référence à une colonne de la requête externe (englobante). Contrairement à une sous-requête classique, qui s'exécute une fois et renvoie un résultat fixe, une sous-requête corrélée est évaluée pour chaque ligne traitée par la requête externe.

Cela les rend puissantes pour les comparaisons ligne par ligne, mais aussi plus coûteuses que les sous-requêtes simples.

Sous-requête simple ou corrélée

La différence essentielle est la suivante : une sous-requête classique ne fait référence ni à la requête externe et peut fonctionner seule. Une sous-requête corrélée dépend de la ligne externe — vous pouvez voir l'alias de la table externe apparaître dans la sous-requête.

Dans l'exemple ci-dessous, le SELECT interne fait référence à e1.department_id de la requête externe, ce qui crée la corrélation.

-- Regular subquery (runs once)
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

-- Correlated subquery (runs once per outer row)
SELECT name, salary, department_id
FROM employees e1
WHERE salary > (
  SELECT AVG(salary)
  FROM employees e2
  WHERE e2.department_id = e1.department_id
);

Créer les tables d'exemple

Créons deux tables que nous utiliserons tout au long de cette leçon : employees et departments. Elles contiennent des données réalistes pour illustrer les sous-requêtes corrélées dans différents scénarios.

CREATE TABLE departments (
  id   INT PRIMARY KEY,
  name VARCHAR(50)
);

CREATE TABLE employees (
  id            INT PRIMARY KEY,
  name          VARCHAR(50),
  department_id INT REFERENCES departments(id),
  salary        NUMERIC(10,2),
  hire_date     DATE
);

INSERT INTO departments VALUES (1,'Engineering'),(2,'Sales'),(3,'HR');

INSERT INTO employees VALUES
  (1,'Alice',  1, 90000, '2020-03-01'),
  (2,'Bob',    1, 75000, '2021-06-15'),
  (3,'Carol',  2, 60000, '2019-01-10'),
  (4,'David',  2, 68000, '2022-09-01'),
  (5,'Eve',    3, 55000, '2020-07-20'),
  (6,'Frank',  1, 95000, '2018-11-05'),
  (7,'Grace',  3, 52000, '2023-02-28'),
  (8,'Henry',  2, 71000, '2021-04-12');

Employés gagnant plus que la moyenne de leur service

Un cas d'utilisation classique des sous-requêtes corrélées consiste à trouver chaque employé dont le salaire dépasse le salaire moyen de son propre service. La requête interne recalcule la moyenne du service pour chaque ligne d'employé de la requête externe.

SELECT e1.name, e1.department_id, e1.salary
FROM employees e1
WHERE e1.salary > (
  SELECT AVG(e2.salary)
  FROM employees e2
  WHERE e2.department_id = e1.department_id
)
ORDER BY e1.department_id, e1.salary DESC;

Utiliser des sous-requêtes corrélées dans SELECT

Les sous-requêtes corrélées ne se limitent pas à la clause WHERE — elles peuvent également apparaître dans la liste SELECT pour calculer une valeur pour chaque ligne. Ici, nous récupérons le salaire de chaque employé ainsi que le salaire moyen de son service, le tout dans une seule requête.

SELECT
  e.name,
  e.salary,
  (
    SELECT ROUND(AVG(e2.salary), 2)
    FROM employees e2
    WHERE e2.department_id = e.department_id
  ) AS dept_avg_salary
FROM employees e
ORDER BY e.department_id, e.name;

Trouver l'employé le mieux rémunéré de chaque service

Nous pouvons utiliser une sous-requête corrélée pour trouver l'employé ayant le salaire maximal dans chaque service. La requête interne trouve le salaire maximal du service de la ligne actuelle, et la requête externe ne conserve que la ligne qui lui correspond.

SELECT e1.name, e1.department_id, e1.salary
FROM employees e1
WHERE e1.salary = (
  SELECT MAX(e2.salary)
  FROM employees e2
  WHERE e2.department_id = e1.department_id
)
ORDER BY e1.department_id;

EXISTS avec une sous-requête corrélée

L'opérateur EXISTS est souvent associé aux sous-requêtes corrélées. Il renvoie TRUE si la requête interne produit au moins une ligne. Ici, nous listons tous les services qui comptent au moins un employé embauché avant 2021.

SELECT d.name AS department
FROM departments d
WHERE EXISTS (
  SELECT 1
  FROM employees e
  WHERE e.department_id = d.id
    AND e.hire_date < '2021-01-01'
);

NOT EXISTS avec une sous-requête corrélée

NOT EXISTS est l'opposé — il renvoie TRUE lorsque la sous-requête corrélée ne trouve aucune ligne correspondante. Cela permet notamment de trouver les enregistrements parents sans enregistrements enfants, comme les services sans employés.

SELECT d.name AS department_without_employees
FROM departments d
WHERE NOT EXISTS (
  SELECT 1
  FROM employees e
  WHERE e.department_id = d.id
);

Sous-requête corrélée dans UPDATE

Les sous-requêtes corrélées fonctionnent également dans les instructions UPDATE. L'exemple suivant ajoute une colonne dept_avg, puis utilise une sous-requête corrélée pour la remplir avec le salaire moyen du service de chaque employé.

ALTER TABLE employees ADD COLUMN dept_avg NUMERIC(10,2);

UPDATE employees e1
SET dept_avg = (
  SELECT ROUND(AVG(e2.salary), 2)
  FROM employees e2
  WHERE e2.department_id = e1.department_id
);

SELECT name, salary, dept_avg FROM employees ORDER BY department_id, name;

Sous-requête corrélée dans DELETE

Vous pouvez également utiliser une sous-requête corrélée dans une instruction DELETE pour supprimer des lignes en fonction de données provenant d'une table associée. La requête ci-dessous supprime les employés dont le salaire est inférieur à 60 % de la moyenne de leur service — un modèle de nettoyage des données.

DELETE FROM employees e1
WHERE e1.salary < (
  SELECT AVG(e2.salary) * 0.60
  FROM employees e2
  WHERE e2.department_id = e1.department_id
);

SELECT name, salary, department_id FROM employees ORDER BY department_id;

Conseil de performance : sous-requête corrélée ou JOIN

Les sous-requêtes corrélées s'exécutent une fois par ligne externe, ce qui peut être lent sur les grandes tables. De nombreuses sous-requêtes corrélées peuvent être réécrites sous la forme d'un JOIN avec une table dérivée ou un CTE pour améliorer les performances. Comprenez les deux modèles et choisissez en fonction de la lisibilité et du plan d'exécution.

-- Correlated version (potentially slower)
SELECT e1.name, e1.salary
FROM employees e1
WHERE e1.salary > (
  SELECT AVG(e2.salary)
  FROM employees e2
  WHERE e2.department_id = e1.department_id
);

-- Equivalent JOIN + derived table (often faster)
SELECT e.name, e.salary
FROM employees e
JOIN (
  SELECT department_id, AVG(salary) AS avg_sal
  FROM employees
  GROUP BY department_id
) dept_avg ON dept_avg.department_id = e.department_id
WHERE e.salary > dept_avg.avg_sal;

Vérification rapide

Vérifiez votre compréhension des sous-requêtes corrélées.

Récapitulatif : sous-requêtes corrélées

Dans cette leçon, vous avez appris qu'une sous-requête corrélée fait référence à une colonne de sa requête externe et est réévaluée pour chaque ligne externe. Points essentiels :

  • Elles peuvent apparaître dans SELECT, WHERE, UPDATE et DELETE.
  • EXISTS / NOT EXISTS s'associent naturellement aux sous-requêtes corrélées pour vérifier la présence de lignes associées.
  • Elles sont expressives, mais peuvent être lentes — envisagez une réécriture sous la forme d'un JOIN lorsque les performances sont importantes.
  • C'est l'alias de la table externe présent dans la sous-requête qui crée la corrélation.

Questions Fréquemment Posées

La leçon « Sous-requêtes corrélées » est-elle gratuite ?

Oui — le texte complet de « Sous-requêtes corrélées » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours SQL Academy, passe à CoddyKit PRO. Le cours SQL Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Sous-requêtes corrélées » ?

Une sous-requête qui dépend de la ligne extérieure. Tu pratiques SQL Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer SQL Academy ?

Aucune expérience préalable n'est requise. SQL Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Sous-requêtes corrélées » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon SQL Academy ?

Oui. Chaque leçon SQL Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Sous-requêtes corrélées
  2. EXISTS et NOT EXISTS
  3. IN, ANY ou ALL
  4. Performances de EXISTS et JOIN
← Retour à SQL Academy