使用单个查询(递归查询)在 mysql 表中查找所有父级

Posted

技术标签:

【中文标题】使用单个查询(递归查询)在 mysql 表中查找所有父级【英文标题】:Finding all parents in mysql table with single query (Recursive Query) 【发布时间】:2012-10-08 12:27:34 【问题描述】:

我有这个架构

样本数据

| 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 |

SQL Fiddle demo.我插入了一些示例数据。

挑战

我需要找到标题为Categories 的记录的所有父项。如何仅通过一个查询获得所有父母? 我的意思是我需要这个结果:

期望的输出

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       

假设我想获取一个包含其所有父项的条目,并且我想使用 where 条件 id = 31,它应该获取上面的记录。

【问题讨论】:

【参考方案1】:
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;

Demo

【讨论】:

这很好,但您能否在回答中逐步解释您是如何做到这一点的。你的想法是什么促使你实现了这一目标。 建议您先运行子查询,看看结果如何,因为子查询是该查询的主要组成部分。这样,可能有助于理解这个查询是如何工作的。 感谢您的反馈。真的很有帮助,我什至读了一些书,如 mysql antipattren 和 mysql 中的树,但找不到解决这个问题的方法,你的方法既简单又有用。再次感谢 如何得到它的逆我的意思是所有孩子的 parent_id Warning: #1287 Setting user variables within expressions is deprecated and will be removed in a future release. Consider alternatives: 'SET variable=expression, ...', or 'SELECT expression(s) INTO variables(s)'.我在MYSQL 8下出现这个错误,谁能帮帮我?

以上是关于使用单个查询(递归查询)在 mysql 表中查找所有父级的主要内容,如果未能解决你的问题,请参考以下文章

php与mysql表中如何求递归求和汇总?

sql SQL查询使用单个值查找表中的重复项。

mysql查询一次在单个查询中在多个表中插入记录

使用MySQL 8.0递归CTE查找层次结构表中的直接后代并传播给父级

MySQL查询表内重复记录

MySQL查询表内重复记录