我有一个目录的表格如下:
因此,每一行都是章节标题,但章节内的章节中可以有章节。因此,上表允许我维持这些关系。
如果章节没有父级,即它不是任何其他章节的子章节,则Parent_ID为“空”。如果一个章节确实有父,那么它的Parent_ID被设置为父章节的ID。
由于章节中可以有多个子章节,因此这些子章节的顺序通过Display_Order列进行管理; 1是第一,等等。
任何人都可以建议一个简洁的SQL查询,它允许我选择整个表,并产生一个完成上述操作的结果吗?基本上,我正在寻找一个反映章节实际层次结构的结果集。下面是ASCII TOC!
Chapter
-- Chapter
---- Chapter
---- Chapter
---- Chapter
-- Chapter
---- Chapter
---- Chapter
Chapter
Chapter
等
答案 0 :(得分: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 ' ';
}
然后创建一个输出树的递归函数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();
就是这样。请注意我跳过了数组初始化,我没有运行这个示例代码,所以它可能有语法错误,但原理就是这个。
这种方法的缺点是,如果您拥有非常多的项目,那么首先将所有内容一次性读取到大型数组时,这将不是最有效的。但对于较少数量的物品,这是一个很好的解决方案。