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