根据 sitepont上的图片,我有一个标准的 mptt 树表。不过,我一辈子都找不到基于所选节点获取整个子树的好方法。
示例(来自该链接页面):假设树是一个菜单,如果有人选择“Cherry” - 我想从“Fruit”节点向下获取所有项目。
所以,我可以使用得到最终的父行(不包括我不想要的根)
SELECT lft, rgt FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1
我认为这 3 个 SELECT 是非常糟糕的 SQL - 但它确实让我 lft & rgt 我可以在进一步的查询中使用它来获取 lft 和 rgt 之间的所有节点 - 从而获得“Cherry”所在的子树。
我用它作为在一个查询中完成所有操作的基础 - 这导致了这种可憎:
SELECT * FROM menu_items
WHERE lft BETWEEN
(SELECT lft FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1)
AND
(SELECT rgt FROM menu_items
WHERE lft < (SELECT lft FROM menu_items WHERE id = 'Cherry')
AND rgt > (SELECT rgt FROM menu_items WHERE id = 'Cherry')
AND lft > 1
ORDER BY lft ASC LIMIT 1)
ORDER BY lft ASC;
这对我来说似乎很讨厌 - 七个 SELECTs !
这可以优雅地完成(最好在一个查询中,但没那么重要 - 可读性>单个查询)?
顺便说一句 - lft 和 rgt 是我的 MPTT 编号字段名称
编辑 ::: 实验后我意识到我笨拙的 SQL 并没有做我想要的。它仅适用于比根深 > 2 层的节点。
我的问题是:参考帖子顶部链接的图表 - 如果用户“选择”任何叶子或子树的父节点,我需要获取整个子树,不包括根。
因此,如果用户选择“樱桃”、“香蕉”、“红色”、“黄色”或“水果”,我需要整个“水果”子树。