【问题标题】:Getting root parent获取根父级
【发布时间】:2012-01-18 18:54:52
【问题描述】:
+--------+---------+-----------+
|   id   | title   | parent_id |
+--------+---------+-----------+
|    1   | Lvl-1   |   null    |
+--------+---------+-----------+
|    2   | Lvl-2   |   null    |
+--------+---------+-----------+
|    3   | Lvl-11  |     1     |
+--------+---------+-----------+
|    4   | Lvl-12  |     1     |
+--------+---------+-----------+
|    5   | Lvl-121 |     4     |
+--------+---------+-----------+

我实际上如何获得每一行的根父级
例如,id 5 的行有id 4 的父行和id 4 的父行有id 1,所以id 5 的根ID 是id 1
我不知道该怎么做,有没有办法通过只使用 1 个查询来解决这个问题

【问题讨论】:

    标签: mysql hierarchical


    【解决方案1】:

    这是一个简短的查询,假设您的表名为foo,并且您想知道<id> 的根:

    SELECT f.id, f.title
    FROM (
        SELECT @id AS _id, (SELECT @id := parent_id FROM foo WHERE id = _id)
        FROM (SELECT @id := <id>) tmp1
        JOIN foo ON @id IS NOT NULL
        ) tmp2
    JOIN foo f ON tmp2._id = f.id
    WHERE f.parent_id IS NULL
    

    【讨论】:

      【解决方案2】:

      【讨论】:

      • 根据他的问题:“我不知道该怎么做,有没有办法通过只使用 1 个查询来解决这个问题”,而不是你在这里的程序循环/连接。解决方案仍然有效,我很好奇是否有“一个选择语句”解决方案
      • SQL Server 能够使用单个语句执行递归查询。 MySQL 没有。这就是为什么它被写成程序。
      • @RolandoMySQLDBA 所以基本上存储过程是唯一的方法吗?我敢打赌,这也可以通过触发器来完成。但是仅通过纯查询就可以实现吗?
      • 在不做一些假设的情况下,不可能有纯 SQL 方式。例如,如果您知道任何 id 的所有路径的最大长度为 7,那么您可能会针对该表编写一个详尽的 LEFT JOIN 查询 6 次。一旦你为长度小于或等于 7 的 id 获得了正确的 SQL,如果现在 id 的长度为 8 或更大怎么办?必须动态更改查询以适应更长的层次结构。同样,这个想法是在查询设计中做出这个假设。存储过程不做任何假设。它只是执行前序树遍历。
      • @RolandoMySQLDBA haiz,这就是为什么 mysql 需要像其他 rdbms 那样实现某种递归函数
      【解决方案3】:

      如果你的树结构不止两层,那么你正在搜索modified preorder tree traversal

      【讨论】:

      • 修改前序树遍历很难维护
      • 存储过程的查询成本很高。这取决于您的用例,什么是最有意义的。
      猜你喜欢
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 2017-12-08
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多