La clause WHERE est l'endroit le plus courant pour utiliser une sous-requête. Elle permet de filtrer le jeu de résultats de la requête principale en fonction des résultats de la requête interne. Dans cette leçon, nous allons explorer différents opérateurs utilisés avec les sous-requêtes dans la clause WHERE.
Quand une sous-requête retourne une seule valeur (une sous-requête scalaire), vous pouvez utiliser les opérateurs de comparaison standards comme =, <>, >, >=, < ou <=.
Scénario : Trouver les noms des acteurs ayant le même prénom que l'acteur dont actor_id = 10.
SELECT
first_name,
last_name
FROM
actor
WHERE
first_name = (SELECT first_name FROM actor WHERE actor_id = 10)
AND actor_id <> 10;
Remarque : Si la sous-requête retourne plus d'une ligne, la requête échouera avec une erreur.
Si une sous-requête retourne plusieurs valeurs (une colonne, plusieurs lignes), vous ne pouvez pas utiliser =, mais vous pouvez utiliser l'opérateur IN.
Scénario : Trouver tous les films appartenant à la catégorie 'Action'.
On commence par trouver le category_id pour 'Action', puis on filtre la table film_category.
SELECT
title
FROM
film
WHERE
film_id IN (
SELECT film_id
FROM film_category
WHERE category_id = (SELECT category_id FROM category WHERE name = 'Action')
);
Remarque : Cet exemple utilise une sous-requête imbriquée dans une autre sous-requête !
L'opérateur NOT IN fonctionne à l'inverse, en excluant les lignes qui correspondent à une valeur de la liste.
L'opérateur EXISTS vérifie l'existence d'au moins un enregistrement dans la sous-requête. Il est souvent plus efficace que IN sur de grands ensembles de données car il s'arrête dès qu'il trouve une correspondance.
Scénario : Trouver tous les clients ayant effectué au moins un paiement.
SELECT
c.first_name,
c.last_name
FROM
customer AS c
WHERE
EXISTS (
SELECT 1
FROM payment AS p
WHERE p.customer_id = c.customer_id
);
Astuce : SELECT 1 est couramment utilisé dans EXISTS car la donnée retournée n'a pas d'importance ; seul le fait qu'une ligne existe compte.
Scénario : Trouver les films dont la durée est supérieure à tous les films de la catégorie 'Comédie'.
SELECT
title,
length
FROM
film
WHERE
length > ALL (
SELECT f.length
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id
WHERE c.name = 'Comedy'
);
=, >) uniquement avec des sous-requêtes qui retournent une seule valeur.WHERE rendent votre code dynamique et permettent une logique de filtrage multi-étapes.