0

情况:
我有一个 mysql 目录表。每个目录都有一个父目录(存储为 parentID),直到根目录的 parentID 为 0。

例如:

rowID: 1, name: Dir1,    parentID: 0 (root directory)
rowID: 2, name: Dir2,    parentID: 0 (root directory)
rowID: 3, name: Subdir1, parentID: 1 (lives in "Dir1")
rowID: 4, name: Subdir2, parentID: 1 (lives in "Dir1")
rowID: 5, name: Subdir3, parentID: 3 (lives in "Subdir1", which in turn lives in "Dir1")
rowID: 6, name: Subdir4, parentID: 5 (lives in "Subdir3", which lives in "Subdir1", which lives in "Dir1")

所以这里有一个3目录深度结构。

我需要构建一个将任何目录加入其父目录并继续这样做的语句,直到最后一个加入的目录的 parentID 为 0(即找到根目录)。您可以将其想象为,给定任何目录,您都可以找到返回给父级的面包屑。

我认为这可能需要一些 MySQL 循环,但对于我的生活,我无法让任何网络示例工作。我什至无法运行一些示例,因为它们似乎存在某种语法错误。谁能帮我开始?

我可以接受任何最简单的结果格式,并提供最佳性能来完成这项工作。可以是一个简单的按正确顺序排列的行号数组(例如 5、3、1、0,表示达到 ID 为 0 的步骤),或者是一个完整的表(最好的),它将是实现这一点的行的有序列表,例如

rowID: 5, name: Subdir3, parentID: 2;
rowID: 3, name: Subdir1, parentID: 1;
rowId: 1, name: Dir1,    parentID: 0;

非常感谢帮助!

4

2 回答 2

0

好的,有时间实际部署一个与所述结构相似的简单数据库。

表格如下:

CREATE TABLE `t_hierarchy` (
    `rowID` INT(11) NULL DEFAULT NULL,
    `name` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_general_ci',
    `parentID` INT(11) NULL DEFAULT NULL
);

我基本上插入了与您在上面给出的完全相同的东西,但使用 NULL 值而不是 0 来表示 root/no parent

我所做的是来自http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/的相当神秘的例子。并更正了列名以适合我的。

由于这只会为您生成递归层次结构,因此我只是在示例中添加了一个愚蠢的联接( ad.rowID = qi.id ):

 SELECT  qi.id, qi.parent, ad.rowId, ad.name, level
FROM    (
        SELECT  @r AS id,
                (
                SELECT  @r := parentID
                FROM    t_hierarchy
                WHERE   rowID = id
                ) AS parent,
                @l := @l + 1 AS level
        FROM    (
                SELECT  @r := 5, -- change this 5 to the directory ID you want to resolve
                        @l := 0,
                        @cl := 0
                ) vars,
                t_hierarchy h
        WHERE   @r <> 0
        ORDER BY
                level DESC
        ) qi, t_hierarchy ad
        WHERE ad.rowID = qi.id

这会生成以下(所需)输出:

id 父 rowId 名称 级别

1 空 1 目录 1 3

3 1 3 子目录 1 2

5 3 5 子目录 3 1

Level 是一个帮助列,它告诉您它必须解决多“深”才能达到此目标。您所要做的就是将@r := 旁边的“5”更改为您想要向下迭代的目录ID。

如果您想切换方向(从上到下),只需按级别列排序([...] WHERE ad.rowID = qi.id ORDER BY level ASC )

希望这可以帮助你。

编辑:qi.id 和 ad.rowID 是重复的,只需删除其中一个;-)...该死的我讨厌那种层次结构的东西

于 2012-08-31T15:25:42.190 回答
0

好吧,可能是您没有找到一个好的网络示例,因为您确实使用了错误的搜索词。所描述的问题完全适合 oracles CONNECT BY PRIOR 语句,并通过谷歌搜索与该语句等效的 mysql,您会发现http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/非常快。

因为写这些东西不是那么容易(而且我没有 mysql-db 可以在这里强奸),所以只需看一下给出的好例子(你甚至可以通过http://explainextended.com/在没有部署函数的情况下做到这一点2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/

如果您仍然不了解这些,我也许可以在家提供帮助。

于 2012-08-27T12:12:00.800 回答