Expressions de Table Communes (CTE) dans MySQL

MySQLMySQLBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire (lab), vous apprendrez à utiliser les Expressions de Table Communes (Common Table Expressions - CTEs) dans MySQL pour améliorer la lisibilité et la maintenabilité des requêtes. Le laboratoire couvre la définition de CTEs simples à l'aide de la clause WITH, l'écriture de CTEs récursives pour les données hiérarchiques, la jointure de CTEs avec des tables et le test de la sortie des requêtes CTE.

Vous commencerez par créer une table d'exemple employees, puis vous définirez une CTE simple pour sélectionner les employés du département 'Sales'. Cela démontrera la syntaxe de base et l'utilisation des CTEs pour décomposer les requêtes complexes en parties plus petites et plus gérables.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mysql(("MySQL")) -.-> mysql/BasicKeywordsandStatementsGroup(["Basic Keywords and Statements"]) mysql/BasicKeywordsandStatementsGroup -.-> mysql/create_table("Table Creation") mysql/BasicKeywordsandStatementsGroup -.-> mysql/select("Data Retrieval") mysql/BasicKeywordsandStatementsGroup -.-> mysql/insert("Data Insertion") subgraph Lab Skills mysql/create_table -.-> lab-550903{{"Expressions de Table Communes (CTE) dans MySQL"}} mysql/select -.-> lab-550903{{"Expressions de Table Communes (CTE) dans MySQL"}} mysql/insert -.-> lab-550903{{"Expressions de Table Communes (CTE) dans MySQL"}} end

Définir une CTE simple avec la clause WITH

Dans cette étape, vous apprendrez à définir une Expression de Table Commune (Common Table Expression - CTE) simple en utilisant la clause WITH dans MySQL. Les CTE sont des ensembles de résultats temporaires et nommés que vous pouvez référencer dans une seule instruction SELECT, INSERT, UPDATE ou DELETE. Elles sont utiles pour décomposer les requêtes complexes en parties plus petites et plus gérables, améliorant ainsi la lisibilité et la maintenabilité.

Comprendre les CTE

Une CTE est essentiellement une sous - requête nommée qui n'existe que pour la durée de l'exécution de la requête. Elle est définie à l'aide de la clause WITH, suivie du nom de la CTE, de la liste des colonnes (optionnelle) et du mot - clé AS, suivi de la sous - requête entre parenthèses.

Créer une table d'exemple

Tout d'abord, créons une simple table nommée employees avec laquelle travailler. Exécutez les instructions SQL suivantes dans votre environnement MySQL. Vous pouvez accéder au client de ligne de commande MySQL en tapant simplement mysql dans votre terminal.

mysql

Ensuite, créez la table :

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department VARCHAR(50),
    salary DECIMAL(10, 2)
);

INSERT INTO employees (employee_id, first_name, last_name, department, salary) VALUES
(1, 'John', 'Doe', 'Sales', 60000.00),
(2, 'Jane', 'Smith', 'Marketing', 75000.00),
(3, 'Robert', 'Jones', 'Sales', 55000.00),
(4, 'Emily', 'Brown', 'IT', 90000.00),
(5, 'Michael', 'Davis', 'Marketing', 70000.00);

Maintenant, quittez le client MySQL :

exit

Définir une CTE simple

Maintenant, définissons une CTE simple pour sélectionner les employés du département 'Sales'.

WITH SalesEmployees AS (
    SELECT employee_id, first_name, last_name, salary
    FROM employees
    WHERE department = 'Sales'
)
SELECT employee_id, first_name, last_name, salary
FROM SalesEmployees;

Explication :

  • WITH SalesEmployees AS (...) : Cela définit une CTE nommée SalesEmployees.
  • SELECT employee_id, first_name, last_name, salary FROM employees WHERE department = 'Sales' : Il s'agit de la sous - requête qui sélectionne les informations des employés de la table employees où le département est 'Sales'.
  • SELECT employee_id, first_name, last_name, salary FROM SalesEmployees : Il s'agit de la requête principale qui sélectionne toutes les colonnes de la CTE SalesEmployees.

Exécuter la requête

Pour exécuter la requête, vous pouvez la sauvegarder dans un fichier nommé sales_employees.sql dans votre répertoire ~/project en utilisant nano :

nano ~/project/sales_employees.sql

Collez le code SQL dans le fichier, enregistrez - le (Ctrl+O) et quittez (Ctrl+X).

Ensuite, exécutez le fichier SQL à l'aide du client de ligne de commande MySQL :

mysql < ~/project/sales_employees.sql

Sortie attendue :

La sortie devrait être une table contenant l'identifiant de l'employé, le prénom, le nom de famille et le salaire de tous les employés du département 'Sales' :

+-------------+------------+-----------+----------+
| employee_id | first_name | last_name | salary   |
+-------------+------------+-----------+----------+
|           1 | John       | Doe       | 60000.00 |
|           3 | Robert     | Jones     | 55000.00 |
+-------------+------------+-----------+----------+
2 rows in set (0.00 sec)

Cela démontre comment définir et utiliser une CTE simple pour filtrer les données d'une table. Dans les étapes suivantes, vous apprendrez des techniques plus avancées, telles que les CTE récursives et la jointure de CTE avec des tables.

Écrire une CTE récursive pour les données hiérarchiques

Dans cette étape, vous apprendrez à écrire une Expression de Table Commune (Common Table Expression - CTE) récursive pour interroger des données hiérarchiques dans MySQL. Les CTE récursives sont particulièrement utiles pour parcourir des structures en arbre, telles que des organigrammes, des systèmes de fichiers ou des hiérarchies de catégories.

Comprendre les CTE récursives

Une CTE récursive est une CTE qui fait référence à elle - même. Elle se compose de deux parties :

  1. Membre d'ancrage (Anchor Member) : Il s'agit du cas de base qui initialise la CTE. C'est une instruction SELECT classique qui définit le point de départ de la récursion.
  2. Membre récursif (Recursive Member) : Cette partie fait référence à la CTE elle - même, permettant à la CTE d'itérer à travers les données hiérarchiques. Elle est combinée avec le membre d'ancrage à l'aide de UNION ALL.

Créer une table d'exemple

Créons une table nommée employee_hierarchy pour représenter la structure hiérarchique des employés au sein d'une entreprise. Exécutez les instructions SQL suivantes dans votre environnement MySQL. Si vous avez fermé le client MySQL à l'étape précédente, rouvrez - le en tapant mysql dans votre terminal.

CREATE TABLE employee_hierarchy (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(50),
    manager_id INT,
    FOREIGN KEY (manager_id) REFERENCES employee_hierarchy(employee_id)
);

INSERT INTO employee_hierarchy (employee_id, employee_name, manager_id) VALUES
(1, 'David', NULL),
(2, 'Emily', 1),
(3, 'Frank', 1),
(4, 'Grace', 2),
(5, 'Henry', 2),
(6, 'Ivy', 3),
(7, 'Jack', 3);

Dans cette table :

  • employee_id est l'identifiant unique de chaque employé.
  • employee_name est le nom de l'employé.
  • manager_id est l'employee_id du manager de l'employé. Le manager de niveau supérieur a une valeur NULL pour manager_id.

Maintenant, quittez le client MySQL :

exit

Écrire une CTE récursive

Maintenant, écrivons une CTE récursive pour récupérer toute la hiérarchie sous un manager spécifique. Dans cet exemple, nous allons récupérer la hiérarchie sous David (employee_id = 1).

WITH RECURSIVE EmployeeHierarchyCTE AS (
    SELECT employee_id, employee_name, manager_id, 0 AS level
    FROM employee_hierarchy
    WHERE manager_id IS NULL  -- Anchor member: Select the top-level manager

    UNION ALL

    SELECT e.employee_id, e.employee_name, e.manager_id, h.level + 1
    FROM employee_hierarchy e
    INNER JOIN EmployeeHierarchyCTE h ON e.manager_id = h.employee_id  -- Recursive member: Join with the CTE itself
)
SELECT employee_id, employee_name, manager_id, level
FROM EmployeeHierarchyCTE
ORDER BY level, employee_name;

Explication :

  • WITH RECURSIVE EmployeeHierarchyCTE AS (...) : Cela définit une CTE récursive nommée EmployeeHierarchyCTE.
  • Membre d'ancrage :
    • SELECT employee_id, employee_name, manager_id, 0 AS level FROM employee_hierarchy WHERE manager_id IS NULL : Cela sélectionne le manager de niveau supérieur (David) et attribue un niveau de 0.
  • Membre récursif :
    • SELECT e.employee_id, e.employee_name, e.manager_id, h.level + 1 FROM employee_hierarchy e INNER JOIN EmployeeHierarchyCTE h ON e.manager_id = h.employee_id : Cela joint la table employee_hierarchy avec la EmployeeHierarchyCTE sur le manager_id pour trouver tous les employés qui dépendent de quelqu'un dans la CTE. Il incrémente le niveau pour chaque niveau de la hiérarchie.
  • UNION ALL : Cela combine les résultats du membre d'ancrage et du membre récursif.
  • SELECT employee_id, employee_name, manager_id, level FROM EmployeeHierarchyCTE ORDER BY level, employee_name : Il s'agit de la requête principale qui sélectionne toutes les colonnes de la EmployeeHierarchyCTE et trie les résultats par niveau et nom d'employé.

Exécuter la requête

Pour exécuter la requête, vous pouvez la sauvegarder dans un fichier nommé employee_hierarchy.sql dans votre répertoire ~/project en utilisant nano :

nano ~/project/employee_hierarchy.sql

Collez le code SQL dans le fichier, enregistrez - le (Ctrl+O) et quittez (Ctrl+X).

Ensuite, exécutez le fichier SQL à l'aide du client de ligne de commande MySQL :

mysql < ~/project/employee_hierarchy.sql

Sortie attendue :

La sortie devrait être une table montrant la hiérarchie des employés sous David :

+-------------+---------------+------------+-------+
| employee_id | employee_name | manager_id | level |
+-------------+---------------+------------+-------+
|           1 | David         |       NULL |     0 |
|           2 | Emily         |          1 |     1 |
|           3 | Frank         |          1 |     1 |
|           4 | Grace         |          2 |     2 |
|           5 | Henry         |          2 |     2 |
|           6 | Ivy           |          3 |     2 |
|           7 | Jack          |          3 |     2 |
+-------------+---------------+------------+-------+
7 rows in set (0.00 sec)

Cela démontre comment utiliser une CTE récursive pour interroger des données hiérarchiques et récupérer toute la hiérarchie sous un nœud spécifique.

Joindre une CTE à une table

Dans cette étape, vous apprendrez à joindre une Expression de Table Commune (Common Table Expression - CTE) à une table dans MySQL. Joindre une CTE à une table vous permet de combiner les résultats de la CTE avec les données d'une autre table, vous permettant ainsi d'effectuer des requêtes et des analyses plus complexes.

Comprendre les jointures de CTE

Joindre une CTE à une table est similaire à joindre deux tables. Vous spécifiez la condition de jointure en utilisant le mot - clé JOIN et la clause ON. La CTE est traitée comme une table virtuelle dans la requête.

Utiliser les tables existantes

Nous continuerons à utiliser les tables employees et employee_hierarchy créées dans les étapes précédentes. Si vous avez sauté ces étapes, veuillez créer les tables en utilisant les scripts SQL fournis dans les étapes 1 et 2.

Créer une CTE pour le salaire moyen par département

Tout d'abord, créons une CTE qui calcule le salaire moyen pour chaque département dans la table employees.

WITH AvgSalaryByDepartment AS (
    SELECT department, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department
)
SELECT * FROM AvgSalaryByDepartment;

Cette CTE, nommée AvgSalaryByDepartment, calcule le salaire moyen pour chaque département et retourne le nom du département et le salaire moyen.

Joindre la CTE à la table employees

Maintenant, joignons cette CTE à la table employees pour récupérer les informations des employés ainsi que le salaire moyen de leur département respectif.

WITH AvgSalaryByDepartment AS (
    SELECT department, AVG(salary) AS avg_salary
    FROM employees
    GROUP BY department
)
SELECT
    e.employee_id,
    e.first_name,
    e.last_name,
    e.department,
    e.salary,
    a.avg_salary
FROM
    employees e
JOIN
    AvgSalaryByDepartment a ON e.department = a.department;

Explication :

  • WITH AvgSalaryByDepartment AS (...) : Cela définit la CTE comme précédemment.
  • SELECT e.employee_id, e.first_name, e.last_name, e.department, e.salary, a.avg_salary FROM employees e JOIN AvgSalaryByDepartment a ON e.department = a.department : Cela sélectionne les informations des employés de la table employees et le salaire moyen de la CTE AvgSalaryByDepartment. La clause JOIN relie les deux en fonction de la colonne department.

Exécuter la requête

Pour exécuter la requête, vous pouvez la sauvegarder dans un fichier nommé employee_avg_salary.sql dans votre répertoire ~/project en utilisant nano :

nano ~/project/employee_avg_salary.sql

Collez le code SQL dans le fichier, enregistrez - le (Ctrl+O) et quittez (Ctrl+X).

Ensuite, exécutez le fichier SQL à l'aide du client de ligne de commande MySQL :

mysql < ~/project/employee_avg_salary.sql

Sortie attendue :

La sortie devrait être une table contenant les informations des employés ainsi que le salaire moyen de leur département :

+-------------+------------+-----------+-----------+----------+------------+
| employee_id | first_name | last_name | department | salary   | avg_salary |
+-------------+------------+-----------+-----------+----------+------------+
|           2 | Jane       | Smith     | Marketing | 75000.00 | 72500.00   |
|           5 | Michael    | Davis     | Marketing | 70000.00 | 72500.00   |
|           4 | Emily      | Brown     | IT        | 90000.00 | 90000.00   |
|           1 | John       | Doe       | Sales     | 60000.00 | 57500.00   |
|           3 | Robert     | Jones     | Sales     | 55000.00 | 57500.00   |
+-------------+------------+-----------+-----------+----------+------------+
5 rows in set (0.00 sec)

Cela démontre comment joindre une CTE à une table pour combiner des données et effectuer des analyses plus complexes.

Tester la sortie des requêtes CTE

Dans cette étape, vous apprendrez à tester la sortie de vos requêtes CTE pour vous assurer qu'elles produisent les résultats attendus. C'est une étape cruciale du processus de développement pour vérifier la justesse de vos requêtes et identifier tout problème potentiel. Nous utiliserons les requêtes créées dans les étapes précédentes pour démontrer le processus de test.

Pourquoi tester les requêtes CTE ?

Tester les requêtes CTE est essentiel pour plusieurs raisons :

  • Justesse : Garantit que les CTE retournent les données correctes en fonction de la logique définie.
  • Intégrité des données : Vérifie que les transformations et les calculs de données au sein des CTE sont précis.
  • Performances : Aide à identifier les éventuels goulots d'étranglement de performance dans les requêtes CTE.
  • Maintenabilité : Rend plus facile la compréhension et la maintenance des requêtes complexes en les décomposant en unités plus petites et testables.

Stratégies de test

Il existe plusieurs stratégies pour tester les requêtes CTE :

  1. Inspection manuelle : Examiner la sortie des requêtes CTE et la comparer aux résultats attendus. Cela convient aux petits ensembles de données et aux requêtes simples.
  2. Test automatisé : Écrire des scripts ou des programmes pour exécuter automatiquement les requêtes CTE et comparer la sortie à des cas de test prédéfinis. Cela est plus efficace pour les grands ensembles de données et les requêtes complexes.
  3. Test unitaire : Tester les CTE individuelles de manière isolée pour s'assurer qu'elles fonctionnent correctement avant de les intégrer dans des requêtes plus grandes.

Tester la CTE simple (étape 1)

Dans l'étape 1, vous avez créé une CTE simple pour sélectionner les employés du département 'Sales'. Pour tester cette requête, vous pouvez inspecter manuellement la sortie et vérifier qu'elle ne contient que des employés du département 'Sales'.

Exécutez à nouveau la requête suivante :

mysql < ~/project/sales_employees.sql

La sortie devrait être :

+-------------+------------+-----------+----------+
| employee_id | first_name | last_name | salary   |
+-------------+------------+-----------+----------+
|           1 | John       | Doe       | 60000.00 |
|           3 | Robert     | Jones     | 55000.00 |
+-------------+------------+-----------+----------+
2 rows in set (0.00 sec)

Vérifiez que John Doe et Robert Jones appartiennent bien au département Sales.

Tester la CTE récursive (étape 2)

Dans l'étape 2, vous avez créé une CTE récursive pour récupérer la hiérarchie des employés. Pour tester cette requête, vous pouvez inspecter manuellement la sortie et vérifier qu'elle représente correctement la structure hiérarchique.

Exécutez à nouveau la requête suivante :

mysql < ~/project/employee_hierarchy.sql

La sortie devrait être :

+-------------+---------------+------------+-------+
| employee_id | employee_name | manager_id | level |
+-------------+---------------+------------+-------+
|           1 | David         |       NULL |     0 |
|           2 | Emily         |          1 |     1 |
|           3 | Frank         |          1 |     1 |
|           4 | Grace         |          2 |     2 |
|           5 | Henry         |          2 |     2 |
|           6 | Ivy           |          3 |     2 |
|           7 | Jack          |          3 |     2 |
+-------------+---------------+------------+-------+
7 rows in set (0.00 sec)

Vérifiez que David est au niveau 0, qu'Emily et Frank dépendent de David (niveau 1), et que Grace, Henry, Ivy et Jack dépendent d'Emily ou de Frank (niveau 2).

Tester la jointure de CTE (étape 3)

Dans l'étape 3, vous avez joint une CTE à la table employees pour récupérer les informations des employés ainsi que le salaire moyen de leur département. Pour tester cette requête, vous pouvez inspecter manuellement la sortie et vérifier que le salaire moyen est correctement calculé pour chaque département.

Exécutez à nouveau la requête suivante :

mysql < ~/project/employee_avg_salary.sql

La sortie devrait être :

+-------------+------------+-----------+-----------+----------+------------+
| employee_id | first_name | last_name | department | salary   | avg_salary |
+-------------+------------+-----------+-----------+----------+------------+
|           2 | Jane       | Smith     | Marketing | 75000.00 | 72500.00   |
|           5 | Michael    | Davis     | Marketing | 70000.00 | 72500.00   |
|           4 | Emily      | Brown     | IT        | 90000.00 | 90000.00   |
|           1 | John       | Doe       | Sales     | 60000.00 | 57500.00   |
|           3 | Robert     | Jones     | Sales     | 55000.00 | 57500.00   |
+-------------+------------+-----------+-----------+----------+------------+
5 rows in set (0.00 sec)

Vérifiez que le salaire moyen du département Marketing est (75000 + 70000) / 2 = 72500, que le salaire moyen du département IT est 90000, et que le salaire moyen du département Sales est (60000 + 55000) / 2 = 57500.

Conclusion

En testant la sortie de vos requêtes CTE, vous pouvez vous assurer qu'elles fonctionnent correctement et produisent les résultats attendus. Cela contribue à améliorer la qualité et la fiabilité de votre analyse et de votre reporting de données. N'oubliez pas d'utiliser une combinaison d'inspection manuelle et de test automatisé pour valider complètement vos requêtes CTE.

Résumé

Dans ce laboratoire, vous avez appris à définir et utiliser des Expressions de Table Communes (Common Table Expressions - CTE) dans MySQL. La première étape consistait à créer une table d'exemple employees, puis à définir une CTE simple nommée SalesEmployees en utilisant la clause WITH. Cette CTE sélectionnait les employés du département 'Sales', démontrant ainsi comment les CTE peuvent décomposer des requêtes complexes en parties plus petites et plus gérables, améliorant ainsi la lisibilité.

Le laboratoire a introduit le concept des CTE comme des ensembles de résultats temporaires et nommés qui n'existent que pour la durée de l'exécution de la requête. Vous avez appris que les CTE sont définies en utilisant la clause WITH, suivie du nom de la CTE et de la sous - requête entre parenthèses. L'exemple a montré comment sélectionner des données de la CTE dans une instruction SELECT ultérieure.