Retour à la liste des articles Articles
5 minutes de lecture

Apprenez à écrire une sous-requête corrélée SQL en 5 minutes

Si vous êtes familier avec la célèbre poupée gigogne russe, alors les sous-requêtes corrélées SQL devraient être faciles à comprendre - les sous-requêtes sont simplement des requêtes imbriquées dans des requêtes. Une sous-requête SQL est souvent appelée requête "interne" ; la requête principale est généralement appelée requête "externe". Cet article couvre tout ce que vous devez savoir sur les sous-requêtes corrélées.

Qu'est-ce qu'une sous-requête SQL corrélée ?

Une sous-requête SQL corrélée est simplement une sous-requête qui est exécutée plusieurs fois - une fois pour chaque enregistrement (ligne) renvoyé par la requête externe (principale). En d'autres termes, la requête externe renvoie un tableau contenant plusieurs lignes ; la requête interne est ensuite exécutée une fois pour chacune de ces lignes. Si votre requête externe renvoie 10 lignes, la requête interne sera exécutée 10 fois. Et si votre requête externe renvoie 100 lignes, la requête interne sera exécutée 100 fois.

Quand faut-il utiliser une sous-requête corrélée SQL ?

Certaines questions relatives aux données ne peuvent être résolues qu'à l'aide de sous-requêtes corrélées. C'est notamment le cas des questions portant sur des données négatives.

Les questions de données négatives surviennent lorsque nous recherchons des enregistrements qui ne satisfont pas à une condition particulière. Voici un exemple de question négative simple : "Obtenez les noms de tous les films qui n'ont pas été produits par Steven Spielberg."

Dans cet article, nous allons résoudre un exemple de question portant sur des données négatives. Avant de le faire, passons d'abord en revue les tables concernées. Nous avons deux tables : la table employee et la table payment_history table. Le second tableau comporte une colonne nommée payment_type qui indique si un paiement fait partie d'un salaire régulier, d'une prime ou d'une récompense. Voyons quelques exemples de données provenant des tables que nous allons utiliser :

employee

employee_id payment_type amount_paid payment_date
100 salary 2000.00 2018-Mar-02
101 salary 1800.00 2018-Mar-02
102 salary 1900.00 2018-Mar-02
101 award 500.00 2018-Mar-08
102 adjustment 124.70 2018-Mar-10

payment_history

employee_id payment_type amount_paid payment_date
100 salary 2000.00 2018-Mar-02
101 salary 1800.00 2018-Mar-02
102 salary 1900.00 2018-Mar-02
101 award 500.00 2018-Mar-08
102 adjustment 124.70 2018-Mar-10

Voici la question négative à laquelle nous aimerions répondre :

"Obtenir les noms des employés qui n'ont jamais reçu de prix".

La requête SQL qui répond à la question précédente est la suivante :

SELECT last_name, first_name
FROM    employee e1
WHERE NOT EXISTS (SELECT ph.last_name 
                                      FROM payment_history ph 
                                      WHERE ph.employee_id = e1.employee_id 
                                      AND ph.payment_type = 'award')

Sous-requêtes SQL corrélées et sous-requêtes simples

La principale différence entre une sous-requête SQL corrélée et une sous-requête simple est que la sous-requête SQL corrélée fait référence à des colonnes de la table de la requête externe.

Dans l'exemple ci-dessus, ph.employee_id = e1.employee_id est une référence à la table de sous-requête externe (e1). Pour identifier une sous-requête corrélée, il suffit de rechercher ce type de références. Si vous en trouvez au moins une, vous avez une sous-requête corrélée !

La partie négative d'une question de données est souvent résolue dans une sous-requête SQL corrélée en utilisant l'opérateur NOT EXISTS dans la clause WHERE. EXISTS est un opérateur toujours suivi d'une sous-requête. Si la sous-requête renvoie au moins un enregistrement, alors EXISTS est évalué à TRUE. Si la sous-requête renvoie un ensemble vide, alors EXISTS est évalué à FALSE. Notez que nous utilisons NOT EXISTS, qui est simplement l'opposé de EXISTS.

Le résultat de la requête précédente est :

first_name last_name
John Smith
Alice Johnson

Un autre exemple de sous-requête corrélée

Dans cet exemple, nous allons essayer d'obtenir les noms de tous les employés qui ont gagné un salaire plus élevé en mars 2018 que leur salaire mensuel moyen pour tous les mois précédents en utilisant une sous-requête corrélée SQL. Voici la requête que nous allons exécuter :

SELECT    first_name, last_name 
FROM       employee e1, payment_history ph
WHERE    e1.employee_id = ph.employee_id 
     AND     amount_paid > = (
                               SELECT AVG(amount_paid) FROM payment_history ph2
                               WHERE ph2.employee_id = e1.employee_id
                                     AND ph2.payment_date  < '01/03/2018'
                                     AND ph2.payment_type = 'salary' 
                               )
     AND    month(ph.payment_date) =3 
     AND    year(ph.payment_date) = 2018 
     AND    ph.payment_type ='salary'

Assez de négativité. Qu'en est-il des questions de données positives ?

Devons-nous utiliser une sous-requête corrélée SQL pour répondre à une question de données positives ? Non, vous n'êtes pas obligé. Vous pouvez néanmoins le faire si vous le souhaitez. Pour les questions positives, nous pouvons généralement nous contenter d'utiliser une condition JOIN ou une relation entre deux tables.

Transformons notre question précédente en question positive et résolvons-la avec une JOIN au lieu d'une sous-requête corrélée. La question devient : "Obtenir les noms des employés qui ont reçu des primes." Et la requête SQL (sans sous-requêtes corrélées) qui répond à cette question est la suivante :

SELECT    first_name, last_name 
FROM       employee e1 
                 JOIN payment_history ph ON  ph.employee_id = e1.employee_id 
WHERE    ph.payment_type =award'

Le résultat est :

first_name last_name
Kate Miller

Avertissement : Votre sous-requête SQL corrélée est susceptible d'être lente.

J'aimerais juste mentionner que nous essayons de ne pas abuser des sous-requêtes corrélées SQL, si possible. Rappelons qu'une sous-requête corrélée s'exécute une fois pour chaque enregistrement renvoyé par la requête externe. Si la requête externe renvoie des milliers et des milliers d'enregistrements, vous pouvez imaginer à quel point les performances de votre requête vont ralentir. En général, vous ne devez utiliser une sous-requête SQL corrélée que si elle est absolument nécessaire.

Essayez vous-même une sous-requête corrélée SQL !

Nous avons vu que les sous-requêtes corrélées sont une partie importante du langage SQL et qu'elles peuvent nous aider à répondre à différentes questions sur les données, notamment les questions négatives. Nous avons également expliqué comment reconnaître une sous-requête SQL corrélée et pourquoi nous devrions généralement essayer d'éviter les sous-requêtes corrélées, si possible, pour des raisons de performances.

Pour améliorer vos compétences en matière de sous-requêtes, essayez le cours SQL pour les débutants de LearnSQL.fr. Une section spécifique est consacrée aux sous-requêtes, avec de nombreux exercices pratiques et des exemples de sous-requêtes corrélées pour vous aider à maîtriser le contenu.