Aller au contenu
M06 · C. Manipuler les données

Sous-requêtes et UNION

Utiliser le résultat d'une requête à l'intérieur d'une autre (dans WHERE, avec IN, EXISTS, ou dans FROM), et assembler deux résultats avec UNION.

1Situer

« Quels produits sont plus chers que la moyenne ? » Pour répondre, il faut d'abord connaître la moyenne... qui est elle-même le résultat d'une requête. Une sous-requête, c'est une question à l'intérieur d'une question. Et quand la présidente veut un seul annuaire avec les clients et le personnel, UNION met deux résultats l'un sous l'autre.

2Comprendre

Une sous-requête est calculée en premier
SELECT nom, prix FROM produits WHERE prix > (SELECT AVG(prix) FROM produits) 216.25 sous-requêteAVG(prix) = 216.25 Tapis berbère · 1200 Théière argentée · 320 Plat à couscous · 250 les 9 autres produits coûtent 216,25 DH ou moins

La requête contient une autre requête entre parenthèses.

1 / 4

La sous-requête qui renvoie une valeur

SELECT nom, prix
FROM produits
WHERE prix > (SELECT AVG(prix) FROM produits);   -- (SELECT ...) vaut 216.25

La sous-requête qui renvoie une liste : IN, NOT IN, EXISTS

-- Les produits déjà commandés au moins une fois
SELECT nom FROM produits
WHERE id IN (SELECT produit_id FROM lignes_commande);
SELECT c.prenom, c.nom
FROM clients c
WHERE EXISTS (SELECT 1 FROM commandes o WHERE o.client_id = c.id);

La sous-requête dans FROM

Une sous-requête peut servir de table temporaire. Elle doit alors avoir un alias.

SELECT ROUND(AVG(total), 2) AS panier_moyen
FROM (SELECT commande_id, SUM(quantite * prix_unitaire) AS total
      FROM lignes_commande
      GROUP BY commande_id) AS t;

Assembler deux résultats : UNION

Exemple simple

Les poupées russes

Une sous-requête est une requête rangée dans une autre, entre parenthèses. On ouvre d'abord la plus petite (la sous-requête), puis on utilise ce qu'on y a trouvé.

SELECT nom FROM produits
WHERE prix > (SELECT AVG(prix) FROM produits);
Exemple simple

Les deux listes d'invités

La mariée et le marié ont chacun leur liste d'invités. UNION les met bout à bout et retire les personnes invitées deux fois. UNION ALL garde les doublons.

3Manipuler

Répondez avec des sous-requêtes ou UNION. Astuce : exécutez d'abord la sous-requête seule pour voir ce qu'elle renvoie.
Pas à pas dans le lab ↗ La base de départ se crée dans votre navigateur (moteur SQL d’environ 700 Ko, chargé une fois).
Résultat

Le résultat de chaque requête s'affichera ici.

Consignes 0 / 4

  1. Le nom et le prix du produit le plus cher (avec une sous-requête et MAX)
  2. Les produits (nom) qui n'ont jamais été commandés
  3. Les clients (prénom, nom) qui habitent à Fès, sans jointure : avec IN et une sous-requête sur villes
  4. Une seule liste de noms : les noms des villes puis ceux des catégories (UNION)

4Pratiquer

Exercice 1 · Sous-requête dans FROM

Calculez le montant moyen d'une commande : d'abord le total de chaque commande (sous-requête dans FROM), puis la moyenne de ces totaux.

Voir le corrigé
SELECT ROUND(AVG(total), 2) AS panier_moyen
FROM (
  SELECT commande_id, SUM(quantite * prix_unitaire) AS total
  FROM lignes_commande
  GROUP BY commande_id
) AS t;

Exercice 2 · EXISTS

Avec EXISTS, listez les catégories qui ont au moins un produit en rupture de stock (stock = 0).

Voir le corrigé
SELECT c.nom
FROM categories c
WHERE EXISTS (
  SELECT 1 FROM produits p
  WHERE p.categorie_id = c.id AND p.stock = 0
);

Exercice 3 · UNION ALL

Un annuaire : le prénom et le nom des clients avec le rôle 'client', et le nom des employés avec leur poste. Triez par rôle.

Voir le corrigé
SELECT CONCAT(prenom, ' ', nom) AS personne, 'client' AS role FROM clients
UNION ALL
SELECT nom, poste FROM employes
ORDER BY role;

5Vérifier

1. Une sous-requête utilisée avec = doit renvoyer...
2. Quelle est la différence entre UNION et UNION ALL ?
3. Pour faire un UNION, les deux SELECT doivent avoir...