Requêtes imbriquées en SQL
Le langage SQL vous permet d'imbriquer une requête dans une autre requête. Cela permet d'écrire une très grande requête qui fera quelque chose de grand et de complexe, bien que la lisibilité du code soit considérablement réduite.
Selon le nombre de valeurs renvoyées par les sous-requêtes, la zone où elles peuvent être appliquées change. Il y a trois options au total :
- La sous-requête renvoie une seule valeur (une colonne et une ligne).
- La sous-requête renvoie une liste de valeurs (un tableau avec une colonne).
- La sous-requête renvoie une table (plusieurs colonnes, n'importe quel nombre de lignes).
Prenons un exemple pour chaque cas.
Sous-requête avec résultat scalaire
Trouvons une liste de tous nos employés de la table des employés dont le salaire est supérieur à la moyenne de l'entreprise. Comment pouvons-nous le faire?
Nous pouvons facilement filtrer les employés en comparant leur salaire à la moyenne si nous le connaissons à l'avance. Parallèlement, nous avons déjà écrit une requête qui nous permet de calculer le salaire moyen des employés de l'entreprise. Rappelons-le :
SELECT AVG(salary) FROM employee
Puis MySQL nous a renvoyé la valeur : 76833.3333 .
Comment maintenant trouver une liste de tous les employés dont le salaire est supérieur à la moyenne ? C'est aussi très simple :
SELECT * FROM employee
WHERE salary > 76833.3333
Le résultat de cette requête sera :
identifiant | nom | profession | salaire |
---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 |
2 | Petrov Petr | Programmeur | 80000 |
4 | Rabinovitch Moisha | Directeur | 200000 |
Et maintenant, nous combinons simplement les deux requêtes en substituant la première requête au lieu de la valeur 76833 :
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
Le résultat de cette requête sera le même :
identifiant | nom | profession | salaire |
---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 |
2 | Petrov Petr | Programmeur | 80000 |
4 | Rabinovitch Moisha | Directeur | 200000 |
Sous-requête avec liste de valeurs
Vous souvenez-vous d'une fois où nous avions une tâche - trouver tous les enregistrements d'une table pour lesquels il n'y a pas d'enregistrements correspondants d'une autre ?
Il y avait aussi cette photo :
Si je ne me trompe pas, la tâche est la suivante : afficher une liste de tous les employés de la table des employés pour lesquels il n'y a pas de tâches dans la table des tâches .
Trouvons également une solution en deux étapes.
Commençons par écrire une requête qui renverra l'identifiant de tous les employés qui ont des tâches dans la table des tâches. Rappelez-vous juste deux choses :
- supprimer les doublons - utilisez le mot-clé DISTINCT.
- supprimer les valeurs NULL du résultat.
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
Et ici, nous avons obtenu un beau résultat d'une telle demande:
id_employé |
---|
1 |
2 |
5 |
4 |
6 |
Écrivons-le temporairement pour plus de commodité sous la forme d'une séquence : 1,2,5,4,6. Écrivons maintenant une deuxième requête - dans la table employee, qui renverra une liste d'employés dont l'id n'est pas contenu dans la première liste :
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
Et le résultat de cette requête :
identifiant | nom | profession | salaire | âge | join_date |
---|---|---|---|---|---|
3 | Ivanov Sergueï | Testeur | 40000 | trente | 2014-01-01 |
Et maintenant, comme dans l'exemple précédent, vous pouvez combiner les deux requêtes en remplaçant simplement le corps de la première requête au lieu de la liste d'identifiants.
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)
GO TO FULL VERSION