0

我有一个如下所示的目录表:

  • ID
  • Parent_ID
  • 章节
  • 显示顺序

因此,每一行都是一个章节标题,但章节中可以有章节,章节中也可以有章节。因此,上表允许我维持这些关系。

如果一个章节没有父章节,即它不是任何其他章节的子章节,则 Parent_ID 为“Null”。如果一个章节确实有父章节,则它的 Parent_ID 设置为父章节的 ID。

由于一个章节内可以有多个子章节,因此这些子章节的顺序通过 Display_Order 列进行管理;1 是第一,等等。

任何人都可以建议一个简洁的 SQL 查询,让我可以选择整个表,并产生执行上述操作的结果吗?本质上,我正在寻找一个反映章节实际层次结构的结果集。ASCII 目录如下!

Chapter
-- Chapter
---- Chapter
---- Chapter
---- Chapter
-- Chapter
---- Chapter
---- Chapter
Chapter
Chapter

等等

4

1 回答 1

0

你不能只使用 SQL 查询(至少在 MySQL 中)。SQL 和 PHP 的一种方法如下:

SELECT id, IFNULL(parent_id, 0) AS parentid, chapter FROM toc ORDER BY parentid, display_order

然后你读取这个行集到一个数组 $a 中,如下所示:

while ($row = mysql_fetch_array($result)) {
    $a[$row['id']]['name'] = $row['chapter'];
    $a[$row['parentid']]['children'][] = $row['id'];
}

它将创建一个第一个索引为 0 的虚构元素。

一个小示例函数,用于打印给定级别的缩进(您可以使用带有填充的 CSS 代替或任何其他方式来生成缩进):

function printIndent($level = 0) {
    for ($j = 0; $j <= $level; $j++) echo '&nbsp';
}

然后创建一个输出树的递归函数 printTree:

function printTree($key = 0, $level = 0) {
    if ($key > 0) {
         printIndent($level);
         echo $a[$key]['name'];
    }
    if (count($a[$key]['children'])
        foreach ($a[$key]['children'] as $child)
             printTree($child, $level + 1);
}

你调用它一次:

printTree();

就是这个。请注意我跳过了数组初始化并且我没有运行这个示例代码,所以它可能有语法错误,但原理就是这个。

这种方法的缺点是,如果您有大量的项目,那么它不是最有效的,因为您首先将所有内容一次读取到一个大数组中。但对于较少数量的项目,这是一个很好的解决方案。

于 2011-10-19T17:16:55.553 回答