Retour à la liste des articles Articles
8 minutes de lecture

5 exemples de sous-requêtes SQL

Les sous-requêtes SQL sont des outils de base si vous voulez communiquer efficacement avec les bases de données relationnelles. Dans cet article, je vous propose cinq exemples de sous-requêtes démontrant comment utiliser des sous-requêtes scalaires, multi-rangs et corrélées dans les clauses WHERE, FROM/JOIN et SELECT.

Une sous-requête, ou requête imbriquée, est une requête placée dans une autre requête SQL. Lorsque vous demandez des informations à une base de données, vous pouvez trouver nécessaire d'inclure une sous-requête dans la clause SELECT, FROM, JOIN ou WHERE. Toutefois, vous pouvez également utiliser des sous-requêtes lors de la mise à jour de la base de données (c'est-à-dire dans les instructions INSERT, UPDATE et DELETE ).

Il existe plusieurs types de sous-requêtes SQL :

  • Lessous-requêtes scalaires renvoient une seule valeur, ou exactement une ligne et exactement une colonne.
  • Les sous-requêtes multi-lignes renvoient soit :
    • Une colonne avec plusieurs lignes (c'est-à-dire une liste de valeurs), ou
    • Plusieurs colonnes avec plusieurs lignes (c'est-à-dire des tableaux).
  • Lessous-requêtes corrélées, où la requête interne repose sur les informations obtenues à partir de la requête externe.

Vous pouvez en savoir plus sur les différents types de sous-requêtes SQL ailleurs ; ici, je veux me concentrer sur les exemples. Comme nous le savons tous, il est toujours plus facile d'appréhender de nouveaux concepts avec des cas d'utilisation concrets. Alors, commençons.

5 exemples de sous-requêtes en SQL

Supposons que nous gérions une galerie d'art. Nous avons une base de données avec quatre tables : paintings, artists, collectors, et sales. Vous pouvez voir les données stockées dans chaque table ci-dessous.

paintings
idnameartist_idlisted_price
11Miracle1300.00
12Sunshine1700.00
13Pretty woman22800.00
14Handsome man22300.00
15Barbie3250.00
16Cool painting35000.00
17Black square #1000350.00
18Mountains41300.00

artists
idfirst_namelast_name
1ThomasBlack
2KateSmith
3NataliWein
4FrancescoBenelli

collectors
idfirst_namelast_name
101BrandonCooper
102LauraFisher
103ChristinaBuffet
104SteveStevenson

sales
iddatepainting_idartist_idcollector_idsales_price
10012021-11-011321042500.00
10022021-11-101421022300.00
10032021-11-10111102300.00
10042021-11-151631034000.00
10052021-11-22153103200.00
10062021-11-2217310350.00

Explorons maintenant ces données en utilisant des requêtes SQL avec différents types de sous-requêtes.

Exemple 1 - Sous-requête scalaire

Nous allons commencer par un exemple simple : Nous voulons lister les tableaux dont le prix est supérieur à la moyenne. En fait, nous voulons obtenir les noms des tableaux ainsi que leurs prix, mais seulement pour ceux qui coûtent plus cher que la moyenne. Cela signifie que nous devons d'abord trouver ce prix moyen ; c'est ici que la sous-requête scalaire entre en jeu :

SELECT name, listed_price
FROM paintings
WHERE listed_price > (
    SELECT AVG(listed_price)
    FROM paintings
);

Notre sous-requête se trouve dans la clause WHERE, où elle filtre l'ensemble des résultats sur la base du prix affiché. Cette sous-requête renvoie une seule valeur : le prix moyen par tableau pour notre galerie. Chaque prix affiché est comparé à cette valeur, et seules les peintures dont le prix est supérieur à la moyenne sont incluses dans le résultat final :

namelisted_price
Pretty woman2800.00
Handsome man2300.00
Cool painting5000.00

Si cela vous semble un peu compliqué, vous pouvez consulter notre cours interactif SQL pour les débutants cours interactif et rafraîchir vos connaissances essentielles de SQL.

Exemples 2 - Sous-requête multi-rangs

Examinons maintenant les sous-requêtes qui renvoient une colonne avec plusieurs lignes. Ces sous-requêtes sont souvent incluses dans la clause WHERE pour filtrer les résultats de la requête principale.

Supposons que nous voulions répertorier tous les collectionneurs qui ont acheté des peintures dans notre galerie. Nous pouvons obtenir le résultat nécessaire en utilisant une sous-requête multi-rangs. Plus précisément, nous pouvons utiliser une requête interne pour lister tous les ID des collectionneurs présents dans la table sales Il s'agit des ID correspondant aux collectionneurs qui ont effectué au moins un achat auprès de notre galerie. Ensuite, dans la requête externe, nous demandons le prénom et le nom de tous les collectionneurs dont l'ID figure dans la sortie de la requête interne. Voici le code :

SELECT first_name, last_name
FROM collectors
WHERE id IN (
    SELECT collector_id
    FROM sales
);

Et voici le résultat :

first_namelast_name
LauraFisher
ChristinaBuffet
SteveStevenson

Il est intéressant de noter que nous pouvons obtenir le même résultat sans sous-requête en utilisant INNER JOIN (ou simplement JOIN). Ce type de jointure ne renvoie que les enregistrements qui peuvent être trouvés dans les deux tables. Ainsi, si nous joignons les tables collectors et la table sales nous obtiendrons une liste de collecteurs avec les enregistrements correspondants dans la table sales de la table. Remarque : J'ai également utilisé le mot-clé DISTINCT ici pour supprimer les doublons du résultat.

Voici la requête :

SELECT DISTINCT collectors.first_name, collectors.last_name
FROM collectors
JOIN sales
  ON collectors.id = sales.collector_id;

Vous pouvez en savoir plus sur le choix entre sous-requête et JOIN ailleurs sur notre blog.

Exemple 3 - Sous-requête multi-rangs avec plusieurs colonnes

Lorsqu'une sous-requête renvoie un tableau comportant plusieurs lignes et plusieurs colonnes, cette sous-requête se trouve généralement dans la clause FROM ou JOIN. Cela vous permet d'obtenir un tableau contenant des données qui n'étaient pas facilement disponibles dans la base de données (par exemple, des données groupées), puis de joindre ce tableau à un autre tableau de votre base de données, si nécessaire.

Disons que nous voulons voir le montant total des ventes pour chaque artiste qui a vendu au moins une peinture dans notre galerie. Nous pouvons commencer par une sous-requête qui utilise la table sales et calcule le montant total des ventes pour chaque ID d'artiste. Ensuite, dans la requête externe, nous combinons ces informations avec les noms et prénoms des artistes pour obtenir le résultat requis :

SELECT
  artists.first_name, 
  artists.last_name, 
  artist_sales.sales
FROM artists
JOIN (
    SELECT artist_id, SUM(sales_price) AS sales
    FROM sales
    GROUP BY artist_id
  ) AS artist_sales
  ON artists.id = artist_sales.artist_id;

Nous attribuons un alias significatif à la sortie de notre sous-requête (artist_sales). De cette façon, nous pouvons facilement nous y référer dans la requête externe, lors de la sélection de la colonne de cette table, et lors de la définition de la condition de jointure dans la clause ON. Remarque : les bases de données émettent une erreur si vous ne fournissez pas d'alias pour le résultat de votre sous-requête.

Voici le résultat de la requête :

first_namelast_namesales
ThomasBlack300
KateSmith4800
NataliWein4250

Ainsi, en une courte requête SQL, nous avons pu calculer le total des ventes pour chaque artiste à partir des données brutes d'une table (sales), puis de joindre ce résultat aux données d'une autre table (artists).

Les sous-requêtes peuvent être très puissantes lorsque nous devons combiner des informations provenant de plusieurs tables. Voyons ce que nous pouvons faire d'autre avec les sous-requêtes.

Exemple 4 - Sous-requête corrélée

L'exemple suivant montre comment les sous-requêtes :

  • peuvent être utilisées dans la clause SELECT, et
  • peuvent être corrélées (c'est-à-dire que la requête principale ou externe s'appuie sur les informations obtenues à partir de la requête interne).

Pour chaque collectionneur, nous voulons calculer le nombre de tableaux achetés dans notre galerie. Pour répondre à cette question, nous pouvons utiliser une sous-requête qui compte le nombre de peintures achetées par chaque collectionneur. Voici la requête complète :

SELECT
  first_name, 
  last_name,
  (
    SELECT count(*) AS paintings
    FROM sales
    WHERE collectors.id = sales.collector_id
  )
FROM collectors;

Remarquez que la requête interne de cet exemple est exécutée pour chaque ligne de la table collectors:

  • La sous-requête est placée dans la clause SELECT parce que nous voulons avoir une colonne supplémentaire avec le nombre de tableaux achetés par le collectionneur correspondant.
  • Pour chaque enregistrement de la table collectors la sous-requête interne calcule le nombre total de tableaux achetés par un collectionneur avec l'ID correspondant.

Voici le résultat :

first_namelast_namepaintings
BrandonCooper0
LauraFisher2
ChristinaBuffet3
SteveStevenson1

Comme vous le voyez, la sortie de la sous-requête (c'est-à-dire le nombre de tableaux) est différente pour chaque enregistrement et dépend de la sortie de la requête externe (c'est-à-dire le collectionneur correspondant). Nous avons donc affaire ici à une sous-requête corrélée.

Consultez ce guide si vous voulez apprendre à écrire des sous-requêtes corrélées en SQL. Pour l'instant, prenons un autre exemple de sous-requête corrélée.

Exemple 5 - Sous-requête corrélée

Cette fois-ci, nous voulons afficher les noms et prénoms des artistes qui n'ont réalisé aucune vente dans notre galerie. Essayons d'accomplir cette tâche en utilisant une sous-requête corrélée dans la clause WHERE:

SELECT first_name, last_name
FROM artists
WHERE NOT EXISTS (
  SELECT *
  FROM sales
  WHERE sales.artist_id = artists.id
);

Voici ce qui se passe dans cette requête :

  • La requête externe répertorie les informations de base sur les artistes, en vérifiant d'abord s'il existe des enregistrements correspondants dans la base de données. sales
  • La requête interne recherche les enregistrements qui correspondent à l'ID de l'artiste qui est actuellement vérifié par la requête externe.
  • S'il n'y a pas d'enregistrements correspondants, le prénom et le nom de l'artiste correspondant sont ajoutés à la sortie :
first_namelast_name
FrancescoBenelli

Dans notre exemple, nous n'avons qu'un seul artiste sans aucune vente pour le moment. Espérons qu'il en décrochera une bientôt.

Il est temps de s'entraîner aux sous-requêtes SQL !

Dans cet article, j'ai couvert plusieurs exemples de sous-requêtes SQL pour vous donner une compréhension générale de la façon dont les sous-requêtes peuvent être utilisées en SQL. Cependant, les expressions de table communes (CTE) sont souvent plus efficaces que les sous-requêtes.

Si vous souhaitez vous entraîner aux sous-requêtes SQL et à d'autres sujets SQL fondamentaux, essayez notre SQL pour les débutants cours interactif. Il comprend 129 défis de codage sur l'interrogation de plusieurs tables, l'agrégation et le regroupement de données, la jonction de tables, l'écriture de sous-requêtes, et bien plus encore.

Vous voulez devenir un maître du SQL ? Découvrez notre parcours d'apprentissage SQL de A à Z. Elle va au-delà des bases et comprend 7 cours interactifs couvrant les fonctions SQL standard, le langage de manipulation des données SQL (DML), les rapports SQL de base, les fonctions de fenêtre, les expressions de table communes (CTE) et les extensions GROUP BY.

Merci de votre lecture et bon apprentissage !