0

根据 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 层的节点。

我的问题是:参考帖子顶部链接的图表 - 如果用户“选择”任何叶子或子树的父节点,我需要获取整个子树,不包括根。

因此,如果用户选择“樱桃”、“香蕉”、“红色”、“黄色”或“水果”,我需要整个“水果”子树。

4

2 回答 2

1

试试下面的查询:

SELECT menu_items.* FROM menu_items ,
(SELECT lft as lft_inner,rgt as rgt_inner FROM menu_items WHERE id = 'Cherry')  
as menu_innner 
WHERE lft < lft_inner  
AND rgt > rgt_inner
AND lft > 1
ORDER BY lft ASC
于 2013-02-01T04:18:04.360 回答
0
------------------------------------------------------------------
SELECT yourtable.* FROM yourtable ,
(SELECT lft as lft_inner,rgt as rgt_inner FROM yourtable WHERE id=178)  
as menu_innner 
WHERE lft > lft_inner  
AND rgt < rgt_inner
AND lft > 1
ORDER BY lft ASC
-----------------------------------------------------------------------
于 2013-04-03T12:16:18.237 回答