La sous-requête renvoie une table
Et enfin, la troisième option est lorsque la sous-requête renvoie la table entière. C'est l'option la plus courante.
Très souvent, il y a des situations où nous voulons modifier un peu une certaine table. Et seulement ensuite joindre (à l'aide de l'opérateur JOIN ON) la table corrigée avec une autre.
Commençons par le cas le plus simple, où nous avons joint deux tables avec un JOIN :
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
Et comme vous vous en souvenez probablement, il y a des tâches dans la table des tâches qui ne sont assignées à personne : employee_id est NULL .
Générons un tableau corrigé , où nous attribuons toutes les tâches pendantes au directeur (son ID = 4).
Pour cela, nous utilisons la fonction IFNULL() :
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
Et le résultat de cette requête :
identifiant | id_employé | nom | date limite |
---|---|---|---|
1 | 1 | Correction d'un bug sur le frontend | 2022-06-01 |
2 | 2 | Correction d'un bug sur le backend | 2022-06-15 |
3 | 5 | Acheter du café | 2022-07-01 |
4 | 5 | Acheter du café | 2022-08-01 |
5 | 5 | Acheter du café | 2022-09-01 |
6 | 4 | Nettoyer le bureau | (NUL) |
7 | 4 | Profite de la vie | (NUL) |
8 | 6 | Profite de la vie | (NUL) |
La cellule corrigée est marquée en rouge.
Remplaçons maintenant notre table corrigée dans la requête :
SELECT * FROM employee e JOIN task t ON e.id = t.emploee_id
Au lieu de la table des tâches .
Une telle requête ressemblerait à ceci :
SELECT * FROM employee e JOIN (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline
FROM task
) t ON e.id = t.emploee_id
Au lieu du mot task , nous avons écrit des parenthèses et y avons placé le corps de la requête.
Soit dit en passant, l'alias t (alias) pour la requête imbriquée était très utile. Une requête imbriquée, contrairement à une table, n'a pas son propre nom, donc l'alias est très déplacé.
Et voici le résultat d'une telle requête :
identifiant | nom | profession | salaire | âge | join_date | identifiant | id_employé | nom |
---|---|---|---|---|---|---|---|---|
1 | Ivanov Ivan | Programmeur | 100000 | 25 | 2012-06-30 | 1 | 1 | Correction d'un bug sur le frontend |
2 | Petrov Petr | Programmeur | 80000 | 23 | 2013-08-12 | 2 | 2 | Correction d'un bug sur le backend |
4 | Rabinovitch Moisha | Directeur | 200000 | 35 | 2015-05-12 | 6 | 4 | Nettoyer le bureau |
4 | Rabinovitch Moisha | Directeur | 200000 | 35 | 2015-05-12 | 7 | 4 | Profite de la vie |
5 | Kirienko Anastasia | Responsable administratif | 40000 | 25 | 2015-10-10 | 4 | 5 | Acheter du café |
5 | Kirienko Anastasia | Responsable administratif | 40000 | 25 | 2015-10-10 | 5 | 5 | Acheter du café |
5 | Kirienko Anastasia | Responsable administratif | 40000 | 25 | 2015-10-10 | 3 | 5 | Acheter du café |
6 | Vaska | chat | 1000 | 3 | 2018-11-11 | 8 | 6 | Profite de la vie |
Notre directeur a pour tâche de "nettoyer le bureau", je pense qu'il trouvera rapidement quelqu'un à qui le déléguer :) Utilisation de l'instruction WITH
Au fait, à partir de la version 8 de MySQL, vous n'avez plus besoin de placer toutes vos sous-requêtes directement dans la requête finale. Ils peuvent être effectués séparément. Pour cela, l'instruction WITH est utilisée .
Elle permet de créer une table virtuelle (nommée query) et son apparence est donnée par un template :
WITH Name AS (request)
Il arrive souvent que votre sous-requête comporte des colonnes sans nom, telles que COUNT(*), auxquelles vous n'avez pas attribué de nom unique. Dans ce cas, l'instruction WITH a la possibilité de spécifier de nouveaux noms de colonne pour la sous-requête.
Sa seconde forme est donnée par le template :
WITH Name(column1, column2, …) AS (request)
Vous pouvez utiliser autant de tables virtuelles (requêtes nommées) que vous le souhaitez et vous y référer les unes les autres. La forme générale de votre demande ressemblera à ceci :
WITH name1 AS (request1),
name2 AS (request2),
name3 AS (request3)
SELECT * FROM name1 JOIN name2 ON …
Prenons maintenant notre requête effrayante :
SELECT * FROM employee e JOIN (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline
FROM task
) t ON e.id = t.emploee_id
Et réécrivez-le en utilisant l'instruction WITH :
WITH task2(id, employee_id, name, deadline)
AS (SELECT id, IFNULL(employee_id, 4), name, deadline FROM task)
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id
Ou vous pouvez vous passer des noms de colonnes, mais vous devrez alors spécifier un alias pour la fonction IFNULL() :
WITH task2 AS (
SELECT id, IFNULL(employee_id, 4) AS employee_id, name, deadline FROM task
)
SELECT * FROM employee e JOIN task2 t ON e.id = t.emploee_id
GO TO FULL VERSION