Skip to content

Sous-requêtes (requêtes imbriquées)

Bonne lecture et bon apprentissage !
Junior TSAFACK – 08/08/2026
⏱️ Temps de lecture estimé : 7 minutes


Dans le langage SQL, une sous-requête (aussi appelée « requête imbriquée » ou « requête en cascade ») consiste à exécuter une requête à l’intérieur d’une autre requête. Une requête imbriquée est souvent utilisée au sein d’une clause WHERE ou de HAVING pour remplacer une ou plusieurs constantes.

Bon à savoir : Les sous-requêtes peuvent être utilisées dans les clauses SELECT, FROM, WHERE, HAVING, INSERT, UPDATE, DELETE, etc. Elles permettent de rendre les requêtes plus dynamiques et plus puissantes.


Type Description
Scalaire Retourne une seule valeur (une ligne, une colonne)
Ligne Retourne une seule ligne (plusieurs colonnes)
Colonne Retourne une seule colonne (plusieurs lignes)
Table Retourne une table entière (plusieurs lignes et colonnes)

Sous-requête qui retourne un seul résultat (scalaire)

Section titled “Sous-requête qui retourne un seul résultat (scalaire)”

L’exemple ci-dessous est un exemple typique d’une sous-requête qui retourne un seul résultat à la requête principale.

SELECT *
FROM table
WHERE nom_colonne = (
SELECT valeur
FROM table2
LIMIT 1
);

Cet exemple montre une requête interne (celle sur table2) qui renvoie une seule valeur. La requête externe, quant à elle, va chercher les résultats de table et filtre les résultats à partir de la valeur retournée par la requête interne.

Remarque : Il est possible d’utiliser n’importe quel opérateur de comparaison tel que =, >, <, >=, <= ou <> avec une sous-requête scalaire.

Une sous-requête peut également retourner une colonne entière. Dès lors, la requête externe peut utiliser la commande IN pour filtrer les lignes qui possèdent une des valeurs retournées par la requête interne.

SELECT *
FROM table
WHERE nom_colonne IN (
SELECT colonne
FROM table2
WHERE cle_etrangere = 36
);

Sous-requête dans la clause FROM (table dérivée)

Section titled “Sous-requête dans la clause FROM (table dérivée)”
SELECT *
FROM (
SELECT *
FROM table
WHERE condition
) AS sous_requete
WHERE autre_condition;

Imaginons un site web qui permet de poser des questions et d’y répondre. Un tel site possède une base de données avec une table pour les questions et une autre pour les réponses.

Table « question » :

q_id q_date_ajout q_titre q_contenu
1 2013-03-24 12:54:32 Comment réparer un ordinateur? Bonjour, j’ai mon ordinateur de cassé, comment puis-je procéder pour le réparer?
2 2013-03-26 19:27:41 Comment changer un pneu? Quel est la meilleur méthode pour changer un pneu facilement?
3 2013-04-18 20:09:56 Que faire si un appareil est cassé? Est-il préférable de réparer les appareils électriques ou d’en acheter de nouveaux?
4 2013-04-22 17:14:27 Comment faire nettoyer un clavier? Bonjour, sous mon clavier il y a beaucoup de poussière, comment procéder? Merci.

Table « reponse » :

r_id r_fk_question_id r_date_ajout r_contenu
1 1 2013-03-27 07:44:32 Bonjour. Pouvez-vous expliquer ce qui ne fonctionne pas avec votre ordinateur? Merci.
2 1 2013-03-28 19:27:11 Bonsoir, le plus simple consiste à faire appel à un professionnel. Cordialement,
3 2 2013-05-09 22:10:09 Des conseils sont disponibles sur internet sur ce sujet.
4 3 2013-05-24 09:47:12 Bonjour. Ça dépend de vous, de votre budget et de vos préférences. Cordialement,

Exemple 1 : Sous-requête qui retourne un seul résultat

Section titled “Exemple 1 : Sous-requête qui retourne un seul résultat”

Avec une telle application, il est peut-être utile de connaître la question liée à la dernière réponse ajoutée sur l’application. Cela peut être effectué via la requête SQL suivante :

SELECT *
FROM question
WHERE q_id = (
SELECT r_fk_question_id
FROM reponse
ORDER BY r_date_ajout DESC
LIMIT 1
);

Résultat :

q_id q_date_ajout q_titre q_contenu
3 2013-04-18 20:09:56 Que faire si un appareil est cassé? Est-il préférable de réparer les appareils électriques ou d’en acheter de nouveaux?

Explication : La sous-requête récupère l’identifiant de la question associée à la dernière réponse ajoutée (la date la plus récente). La requête principale utilise ensuite cet identifiant pour afficher les détails de la question correspondante.


Exemple 2 : Sous-requête qui retourne une colonne

Section titled “Exemple 2 : Sous-requête qui retourne une colonne”

Imaginons maintenant que l’on souhaite obtenir toutes les questions qui ont reçu une réponse entre 2 dates.

SELECT *
FROM question
WHERE q_id IN (
SELECT r_fk_question_id
FROM reponse
WHERE r_date_ajout BETWEEN '2013-01-01' AND '2013-12-31'
);

Résultat :

q_id q_date_ajout q_titre q_contenu
1 2013-03-24 12:54:32 Comment réparer un ordinateur? Bonjour, j’ai mon ordinateur de cassé, comment puis-je procéder pour le réparer?
2 2013-03-26 19:27:41 Comment changer un pneu? Quel est la meilleur méthode pour changer un pneu facilement?
3 2013-04-18 20:09:56 Que faire si un appareil est cassé? Est-il préférable de réparer les appareils électriques ou d’en acheter de nouveaux?

Explication : La sous-requête retourne une liste d’identifiants de questions qui ont reçu une réponse entre 2013-01-01 et 2013-12-31. La requête principale utilise IN pour sélectionner toutes ces questions.


Exemple 3 : Sous-requête dans la clause FROM (table dérivée)

Section titled “Exemple 3 : Sous-requête dans la clause FROM (table dérivée)”

Pour obtenir le nombre de réponses par question :

SELECT q.q_titre, stats.nb_reponses
FROM question q
INNER JOIN (
SELECT r_fk_question_id, COUNT(*) AS nb_reponses
FROM reponse
GROUP BY r_fk_question_id
) AS stats ON q.q_id = stats.r_fk_question_id;

Résultat :

q_titre nb_reponses
Comment réparer un ordinateur? 2
Comment changer un pneu? 1
Que faire si un appareil est cassé? 1
Comment faire nettoyer un clavier? 0

Explication : La sous-requête dans FROM crée une table temporaire contenant le nombre de réponses par question. La requête principale joint cette table dérivée avec la table des questions pour afficher le résultat.


Pour obtenir les questions qui ont au moins une réponse :

SELECT *
FROM question q
WHERE EXISTS (
SELECT 1
FROM reponse r
WHERE r.r_fk_question_id = q.q_id
);

Résultat : Les questions 1, 2 et 3 (celles qui ont des réponses). (Nous étudierons EXISTS en détail au chapitre suivant.)


  1. Utilisez des alias clairs pour les colonnes et les sous-requêtes pour améliorer la lisibilité.

  2. Évitez les sous-requêtes corrélées si possible : elles sont exécutées une fois par ligne de la requête externe, ce qui peut être lent sur de grandes tables.

  3. Préférez les jointures aux sous-requêtes pour des performances optimales (souvent, un JOIN est plus efficace).

  4. Testez vos sous-requêtes séparément pour vous assurer qu’elles retournent les résultats attendus.

  5. Limitez l’utilisation des sous-requêtes dans la clause SELECT : elles peuvent dégrader les performances. Utilisez plutôt des jointures ou des agrégations.

  6. Pour les sous-requêtes scalaires, gérez le cas où elles retournent NULL : utilisez COALESCE ou IFNULL si nécessaire.


Sous-requêtes corrélées vs non corrélées

Section titled “Sous-requêtes corrélées vs non corrélées”
Type Description Exemple
Non corrélée La sous-requête est indépendante de la requête externe. Elle n’est exécutée qu’une seule fois. SELECT * FROM table WHERE id IN (SELECT id FROM autre_table)
Corrélée La sous-requête dépend de la requête externe. Elle est exécutée pour chaque ligne de la requête externe. SELECT * FROM table t1 WHERE EXISTS (SELECT 1 FROM autre_table t2 WHERE t2.fk = t1.id)

Vous savez désormais comment utiliser les sous-requêtes pour rendre vos requêtes plus puissantes et plus dynamiques. Mais comment vérifier simplement si une sous-requête retourne des résultats sans avoir à compter les lignes ?

👉 Chapitre 40 : EXISTS – Vérifier l’existence de lignes


Bonne continuation !
Junior TSAFACK – 08/08/2026