Visualiseur — Sous-requêtes SQL
Une sous-requête est une requête imbriquée dans une autre. Le moteur l’exécute en premier, puis injecte son résultat dans la requête principale. Choisissez un type de sous-requête et naviguez étape par étape.
Le point le plus difficile à assimiler dans les sous-requêtes est leur ordre d’exécution : la sous-requête est traitée avant la requête principale, et non pas de haut en bas comme on lirait du code. L’outil rend cet ordre explicite en forçant l’apprenant à passer par l’étape de la sous-requête avant de voir la table principale filtrée. La distinction visuelle entre le bloc jaune (résultat de la sous-requête) et le bloc bleu (table principale) évite la confusion fréquente entre ce que produit chaque niveau de la requête.
Qu’est ce qu’une sous-requête et pourquoi le moteur l’exécute en premier
Une sous-requête est une instruction SELECT imbriquée à l’intérieur d’une autre requête SQL. Le moteur l’exécute toujours en premier, puis injecte son résultat dans la requête principale comme s’il s’agissait d’une valeur, d’une liste ou d’une table temporaire. Cette priorité d’exécution est le point central que l’outil matérialise : la sous-requête est mise en surbrillance orange à l’étape 1, avant que la requête principale ne soit traitée.
Les sous-requêtes permettent de filtrer des données en fonction d’un calcul dynamique, d’éviter des jointures explicites dans certains cas, ou d’ajouter une colonne calculée directement dans le SELECT. Elles peuvent apparaître dans trois positions syntaxiques : dans la clause WHERE (avec IN ou EXISTS), dans la clause FROM (table dérivée), ou directement dans la liste de colonnes du SELECT (sous-requête scalaire).
Les 4 scénarios et le jeu de données
L’outil utilise deux tables : employes (8 lignes avec id, nom, departement, salaire) et commandes (6 lignes avec id, client_id, produit, montant). La table commandes fait référence aux employés via client_id, ce qui permet de croiser les deux sources selon différentes techniques. Les quatre onglets correspondent aux quatre formes les plus courantes de sous-requêtes en SQL.
-- Table employes (8 lignes)
SELECT * FROM employes;
-- id | nom | departement | salaire
-- 1 | Alice | Ventes | 2800
-- 2 | Bob | Tech | 3500
-- 3 | Claire | Ventes | 3100
-- 4 | David | Interim | 1800
-- 5 | Emma | Ventes | 2600
-- 6 | Farid | Interim | 1900
-- 7 | Gaëlle | Tech | 4000
-- 8 | Hugo | Interim | 2100
-- Table commandes (6 lignes)
SELECT * FROM commandes;
-- id | client_id | produit | montant
-- 1 | 1 | Stylo | 12
-- 2 | 3 | Cahier | 8
-- 3 | 1 | Règle | 5
-- 4 | 7 | Crayon | 3
-- 5 | 3 | Gomme | 2
-- 6 | 2 | Stylo | 12
Scénario 1 : WHERE IN avec sous-requête
L’onglet WHERE IN (bleu) simule la requête la plus intuitive. La sous-requête SELECT client_id FROM commandes est exécutée en premier et produit la liste [1, 3, 7, 2]. L’outil affiche cette liste dans un bloc jaune à droite, symbolisant son injection dans la requête principale. La table employes est ensuite parcourue : les lignes dont id figure dans cette liste passent en vert, les autres en gris.
WHERE IN est adapté quand la sous-requête retourne un petit ensemble de valeurs distinctes. Sur de très grandes tables, la liste générée par la sous-requête peut être longue et ralentir la comparaison. Dans ce cas, EXISTS ou une jointure sont généralement plus performants.
SELECT nom, salaire
FROM employes
WHERE id IN (
SELECT client_id -- Exécutée en premier → [1, 3, 7, 2]
FROM commandes
);
-- Résultat : Alice (2800), Bob (3500), Claire (3100), Gaëlle (4000)
Scénario 2 : WHERE EXISTS avec sous-requête corrélée
L’onglet WHERE EXISTS (vert) montre la différence fondamentale avec WHERE IN. La sous-requête EXISTS ne produit pas une liste de valeurs : elle teste pour chaque ligne de la table principale si au moins une ligne correspondante existe dans la table secondaire. Dès qu’une correspondance est trouvée, le moteur arrête la recherche pour cette ligne (court-circuit). L’outil explicite ce comportement dans la description de l’étape 2.
La sous-requête corrélée WHERE c.client_id = e.id fait référence à e.id, la ligne courante de la table principale. Elle est réévaluée pour chaque ligne d’employes, contrairement à WHERE IN dont la sous-requête n’est évaluée qu’une seule fois. Ce mécanisme rend EXISTS plus performant lorsque la table secondaire est grande et que l’on recherche simplement une existence, sans avoir besoin des valeurs elles-mêmes.
SELECT nom, salaire
FROM employes e
WHERE EXISTS (
SELECT 1 -- Retourne TRUE dès qu'une ligne correspond
FROM commandes c
WHERE c.client_id = e.id -- Corrélée : réévaluée par ligne
);
-- Même résultat que WHERE IN : Alice, Bob, Claire, Gaëlle
Scénario 3 : Sous-requête dans la clause FROM (table dérivée)
L’onglet FROM (sous-req) (violet) illustre un usage plus avancé : la sous-requête génère une table temporaire nommée stats qui est ensuite interrogée comme n’importe quelle table ordinaire. La sous-requête calcule le salaire moyen par département via GROUP BY. L’outil affiche cette table dérivée dans un bloc jaune à l’étape 1, puis montre le filtre WHERE avg_sal > 2500 appliqué sur ses lignes à l’étape 2.
Ce pattern est particulièrement utile pour filtrer sur un résultat agrégé sans recourir à HAVING. Il permet aussi de réutiliser un calcul complexe comme source de données pour plusieurs filtres ou jointures dans la même requête.
SELECT dept, avg_sal
FROM (
SELECT departement AS dept, -- Sous-requête exécutée en premier
AVG(salaire) AS avg_sal -- Produit la table dérivée "stats"
FROM employes
GROUP BY departement
) AS stats
WHERE avg_sal > 2500;
-- Résultat :
-- Ventes | 2833 (moyenne des salaires Alice, Claire, Emma)
-- Tech | 3750 (moyenne des salaires Bob, Gaëlle)
Scénario 4 : Sous-requête scalaire dans le SELECT
L’onglet Scalaire (orange) montre le cas où la sous-requête retourne une unique valeur numérique — ici AVG(salaire) calculé sur l’ensemble de la table. Cette valeur unique est injectée à deux endroits simultanément : comme colonne calculée dans le SELECT (colonne salaire_moyen répétée sur chaque ligne du résultat), et dans le WHERE pour filtrer les employés dont le salaire dépasse la moyenne.
Une sous-requête scalaire doit impérativement retourner exactement une ligne et une colonne. Si elle retourne plusieurs lignes, le moteur lève une erreur. C’est pourquoi elle contient toujours une fonction d’agrégation (AVG, MAX, MIN, COUNT) ou un filtre garantissant l’unicité du résultat.
SELECT nom,
salaire,
(SELECT AVG(salaire) FROM employes) AS salaire_moyen -- Valeur scalaire
FROM employes
WHERE salaire > (SELECT AVG(salaire) FROM employes); -- Même valeur injectée dans WHERE
-- AVG(salaire) = 2850 (arrondi)
-- Résultat : Bob (3500), Claire (3100), Gaëlle (4000)
Ce que l’outil apporte à la compréhension
Le point le plus difficile à assimiler dans les sous-requêtes est leur ordre d’exécution : la sous-requête est traitée avant la requête principale, et non pas de haut en bas comme on lirait du code. L’outil rend cet ordre explicite en forçant l’apprenant à passer par l’étape de la sous-requête avant de voir la table principale filtrée. La distinction visuelle entre le bloc jaune (résultat de la sous-requête) et le bloc bleu (table principale) évite la confusion fréquente entre ce que produit chaque niveau de la requête.
ARTICLES LIÉS
Que spécifie le mot-clé SQL FROM et comment l’utiliser ?
La commande SQL FROM indique au moteur SQL la table exacte qui contient les données à extraire, filtrer ou supprimer dans une requête. Syntaxe de baseUtiliser FROM avec une table uniqueUtiliser un alias de tableJoindre deux tables avec JOINJoindre plusieurs tablesUtiliser une sous-requête dans FROMCompatibilité SGBDBonnes pratiquesCas pratiqueErreurs courantes Syntaxe de…
SQL UPDATE: Comment mettre à jour des données en SQL ?
La commande SQL UPDATE modifie les données existantes dans une table de base de données. Cette instruction cible des lignes spécifiques via une clause WHERE et remplace les valeurs des colonnes désignées par la clause SET. Les développeurs utilisent UPDATE pour corriger des erreurs, actualiser des prix, changer des statuts ou synchroniser…
SQL DELETE: Comment utiliser DELETE en SQL ?
La commande SQL DELETE supprime définitivement une ou plusieurs lignes d’une table en ciblant les enregistrements via une clause WHERE. Syntaxe de baseSupprimer une ligne via son identifiantSupprimer avec une condition multipleSélectionner les enregistrements avant de supprimerSupprimer avec une transactionSupprimer sur plusieurs tables avec une jointureSupprimer avec EXISTSImplémenter le soft DELETECompatibilité SGBDBonnes…
OUTER JOIN en SQL: C’est quoi une jointure externe ?
OUTER JOIN en SQL est l’opérateur SQL qui assemble les enregistrements de deux tables tout en conservant les lignes sans correspondance, en affichant NULL pour les colonnes manquantes. Contrairement à INNER JOIN, une jointure externe ne se limite pas aux seuls enregistrements appariés entre les deux tables interrogées. Syntaxe de OUTER JOIN en SQLComment…
FULL JOIN: Qu’est-ce qu’une jointure complète en SQL ?
Le FULL JOIN, aussi écrit FULL OUTER JOIN, est une instruction SQL qui conserve l’intégralité des enregistrements des deux tables engagées dans la requête. Lorsqu’une ligne de la table gauche ne trouve aucun équivalent dans la table droite, toutes les colonnes manquantes reçoivent automatiquement la valeur NULL. Ce mécanisme s’applique symétriquement aux lignes…