Dans les leçons précédentes, nous avons utilisé des sous-requêtes "autonomes" qui pouvaient être exécutées seules. Dans cette leçon, nous introduisons les sous-requêtes corrélées — un type avancé de sous-requête qui dépend des valeurs de la requête principale.
Une sous-requête est corrélée lorsqu'elle fait référence à une colonne d'une table de la requête principale. Contrairement à une sous-requête classique, une sous-requête corrélée ne peut pas être exécutée indépendamment de la requête principale.
Comment ça fonctionne :
WHERE (ou SELECT).Note sur la performance : Une sous-requête corrélée peut être exécutée une fois pour chaque ligne de la requête principale, ce qui peut être plus lent qu'un JOIN ou une sous-requête classique sur de grands ensembles de données.
L'usage le plus courant est de comparer la valeur d'une ligne à un ensemble de données lié spécifiquement à cette ligne.
Scénario : Trouver tous les films dont le coût de remplacement est supérieur à la moyenne des films de la même catégorie de classification (ex. G, PG, R).
SELECT
title,
rating,
replacement_cost
FROM
film AS f1
WHERE
replacement_cost > (
SELECT AVG(replacement_cost)
FROM film AS f2
WHERE f1.rating = f2.rating
);
f1.rating = f2.rating lie la requête interne à la ligne courante de la requête principale.Vous pouvez utiliser des sous-requêtes corrélées pour récupérer des données descriptives ou des agrégats pour chaque ligne sans utiliser la clause GROUP BY.
Scénario : Afficher la liste des catégories et le titre du film le plus long dans chaque catégorie.
SELECT
c.name AS category_name,
(
SELECT f.title
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
WHERE fc.category_id = c.category_id
ORDER BY f.length DESC
LIMIT 1) AS longest_film_title
FROM
category AS c;
Nous avons vu l'opérateur EXISTS dans la leçon précédente. EXISTS est presque toujours utilisé avec une sous-requête corrélée.
Scénario : Trouver les clients ayant loué au moins un film dans un magasin spécifique (Magasin 1).
SELECT
first_name,
last_name
FROM
customer AS c
WHERE
EXISTS (
SELECT 1
FROM rental AS r
INNER JOIN inventory AS i ON r.inventory_id = i.inventory_id
WHERE r.customer_id = c.customer_id
AND i.store_id = 1
);