作为对this question的回复,Bill Karwin发布了以下查询,以便在给定任何特定树节点id的情况下撤回有序子树:
SELECT d.`iD`, d.`subsectionOf`,
CONCAT(REPEAT('-', p.`len`), d.`name`) as hier,
p.`len`, p.`ancestor`, p.`descendant`,
GROUP_CONCAT(crumbs.`ancestor`) AS breadcrumbs
FROM `TreeData` AS d
JOIN `TreePaths` AS p ON d.`iD` = p.`descendant`
JOIN `TreePaths` AS crumbs ON crumbs.`descendant` = p.`descendant`
WHERE p.`ancestor` = 1
GROUP BY d.`iD`
ORDER BY breadcrumbs;
我自己已经在我自己的几个项目中成功使用了这个查询,但我意识到我并不确切地知道这个查询的工作原理和原因。我觉得我对闭包表设计有一个很好的理解(主要是通过阅读Karwin的SQL处理分层数据的套牌)。尽管如此,我不能轻易地“手指追踪”这个查询并解释它是如何构建结果集的。
具体来说,我最难理解“treePaths”表上的第二个JOIN(我理解为记录每个节点/叶子的祖先和后代关系的实际闭包表)。这如何创建面包屑结果?