在PHP中递归遍历简单树

时间:2010-02-23 13:50:29

标签: php mysql recursion

我有一个简单的树,其形状如下

    ROOT
     /\
    A  B
   /    \ 
  A1     B1
          \
           B11

它存储在自引用的DB表CLASSES中。

 ID |  CLASS_ID  | PARENT_ID
 ---------------------------
  1 |     ROOT   |  
  2 |     A      | ROOT
  3 |     A1     | A
  4 |     B      | ROOT
  5 |     B1     | B
  6 |     B11    | B1
 ---------------------------

等等,这只是一个例子,class_id和parent_id列是整数,但我只是为这个例子制作了字符,所以你明白了。

然后我有了第二个表CHILDREN,我想在最后看起来像这样,

 ID | CLASS_ID   | CHILD_CLASS_ID
 --------------------------------
  1 |     ROOT   |  A
  2 |     ROOT   |  A1
  3 |     ROOT   |  B
  4 |     ROOT   |  B1
  5 |     ROOT   |  B11
  6 |     A      |  A1
  7 |     B      |  B1
  8 |     B      |  B11
  9 |     B1     |  B11
 ---------------------------

所以基本上如果一个类低于其分支中的任何类,它就是所有更高类的子类。我知道这绝对是一个递归问题,但我是PHP新手可以真正使用一些帮助。我正在运行mysql。我还要提一下,我将向后穿越。所以我在底部插入类。一个例子是要插入的下一个类是A11,然后我需要遍历以查找所有更高的类并使它们成为A11的父类。

2 个答案:

答案 0 :(得分:2)

希望我已经掌握了你想要做的事情。你是否必须向后工作才能创建子表?

如果您从上到下工作,您可以使用MySQL GROUP_CONCAT()

收集每个父母的所有子ID
SELECT PARENT_ID, GROUP_CONCAT(CLASS_ID) AS CHILDREN
FROM CLASSES
GROUP BY PARENT_ID

这应该返回类似:

| PARENT_ID | CHILDREN      |
-----------------------------
| ROOT      | A,A1,B,B1,B11 |
| A         | A1            |
| B         | B1,B11        |
| A1        |               |
| B1        | B11           |
| B11       |               |
-----------------------------

然后你可以打破它并填充你的CHILDREN表吗?

答案 1 :(得分:0)

你必须这样做吗?在我看来,这是一个非常糟糕的方式。您的查询变得复杂,就像您使用邻接列表一样,这很简单。

看看这个。

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/