Maison >base de données >tutoriel mysql >Comment trouver toutes les entrées parent dans une table MySQL à l'aide d'une seule requête récursive ?

Comment trouver toutes les entrées parent dans une table MySQL à l'aide d'une seule requête récursive ?

DDD
DDDoriginal
2024-11-30 19:23:15269parcourir

How to Find All Parent Entries in a MySQL Table Using a Single Recursive Query?

Recherche de tous les parents dans une table MySQL avec une requête unique (requête récursive)

Les tables telles que les menus ou les catégories ont souvent des structures hiérarchiques où les entrées sont liés les uns aux autres via une relation parent-enfant. Dans de tels scénarios, récupérer tous les parents d'une entrée particulière peut devenir un défi, en particulier lorsque l'on tente de le faire avec une seule requête.

Considérez le schéma suivant contenant des entrées de menu :

| ID |             TITLE | CONTROLLER |            METHOD | PARENT_ID |
|----|-------------------|------------|-------------------|-----------|
|  1 |         Dashboard |      admin |         dashboard |         0 |
|  2 |           Content |      admin |           content |         0 |
|  3 |           Modules |      admin |           modules |         0 |
|  4 |             Users |      admin |             users |         0 |
|  5 |          Settings |      admin |          settings |         0 |
|  6 |           Reports |      admin |           reports |         0 |
|  7 |              Help |      admin |              help |         0 |
|  8 |             Pages |    content |             pages |         2 |
|  9 |             Media |    content |             media |         2 |
| 10 |          Articles |    content |          articles |         2 |
| 11 |            Menues |    content |            menues |         2 |
| 12 |         Templates |    content |         templates |         2 |
| 13 |            Themes |    content |            themes |         2 |
| 14 |              Blog |    content |              blog |         2 |
| 15 |             Forum |    content |             forum |         2 |
| 16 |      Core Modules |    modules |       core_module |         3 |
| 17 |      User Modules |    modules |       user_module |         3 |
| 18 |         All Users |      users |         all_users |         4 |
| 19 |            Groups |      users |            groups |         4 |
| 20 |       Permissions |      users |       permissions |         4 |
| 21 | Import and Export |      users |     import_export |         4 |
| 22 |        Send Email |      users |         send_mail |         4 |
| 23 |     Login Records |      users |     login_records |         4 |
| 24 |  General Settings |   settings |  general_settings |         5 |
| 25 |    Email Settings |   settings |    email_settings |         5 |
| 26 |   Popular Content |    reports |   popular_content |         6 |
| 27 | Most Active Users |    reports | most_active_users |         6 |
| 28 |     Documentation |       help |     documentation |         7 |
| 29 |             About |       help |             about |         7 |
| 30 |          Products |   products |           product |        17 |
| 31 |        Categories | categories |          category |        17 |

Le but est de retrouver tous les parents d'une entrée avec l'ID 31 (Catégories) à l'aide d'une seule requête. Pour y parvenir, nous pouvons utiliser une requête récursive :

SELECT T2.id, T2.title,T2.controller,T2.method,T2.url
FROM (
    SELECT
        @r AS _id,
        (SELECT @r := parent_id FROM menu WHERE id = _id) AS parent_id,
        @l := @l + 1 AS lvl
    FROM
        (SELECT @r := 31, @l := 0) vars,
        menu m
    WHERE @r <> 0) T1
JOIN menu T2
ON T1._id = T2.id
ORDER BY T1.lvl DESC;

Cette requête utilise une expression de table commune (CTE) pour récupérer de manière itérative les parents d'une entrée. La sous-requête vars initialise les variables @r et @l, qui représentent respectivement l'ID de l'entrée actuelle et le niveau de récursion. La sous-requête principale, T1, utilise ensuite une requête récursive pour trouver le parent de l'entrée actuelle tout en incrémentant le niveau.

Enfin, le CTE T1 est joint à la table de menu, T2, pour récupérer les détails de chaque entrée parentale. La clause ORDER BY T1.lvl DESC classe les résultats par ordre décroissant de niveau, garantissant que les parents les plus proches sont affichés en premier.

En utilisant cette requête récursive, nous pouvons obtenir le résultat souhaité suivant :

id | title        |  controller  | method      | url     | parent_id 
----------------------------------------------------------------  
3  | Modules      |   admin      | modules     | (NULL)  | 0           
17 | User Modules |   modules    | user_module | (NULL)  | 3           
31 | Categories   |   categories | category    | (NULL)  | 17       

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn