【问题标题】:Help with writing a SQL query for Nested Sets帮助编写嵌套集的 SQL 查询
【发布时间】:2008-11-25 03:19:24
【问题描述】:

我正在使用嵌套集在数据库中存储一棵树。该表的字段是 id、lft、rgt 和 name。

给定一个节点 ID,我需要找到它的所有直接子节点(不是孙子节点),它们本身就是叶节点。

【问题讨论】:

    标签: sql nested-sets


    【解决方案1】:

    文章Managing Hierarchical Data in MySQL 给出了如何使用嵌套集的一个很好的例子,并给出了许多常见查询的例子,包括这个。

    这里是如何找到一个节点的直接子节点:

    SELECT node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
    FROM nested_category AS node,
        nested_category AS parent,
        nested_category AS sub_parent,
        (
            SELECT node.name, (COUNT(parent.name) - 1) AS depth
            FROM nested_category AS node,
            nested_category AS parent
            WHERE node.lft BETWEEN parent.lft AND parent.rgt
            AND node.name = '**[[MY NODE]]**'
            GROUP BY node.name
            ORDER BY node.lft
        )AS sub_tree
    WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.name = sub_tree.name
    GROUP BY node.name
    HAVING depth = 1
    ORDER BY node.lft;
    

    然后将其与叶节点的rgt 等于lft + 1 的事实结合起来,您就设置好了。 请原谅双关语。

    【讨论】:

    【解决方案2】:

    我们在数据库中使用嵌套集进行了大量开发。父节点的左值和右值将始终为其子节点设置值的边界。

    使用 lft 和 rgt 值查找任何节点的子节点:

    select 
        child.id, 
        child.lft, 
        child.rgt 
    from 
        nodes child, 
        nodes parent 
    where 
        child.lft between parent.lft and parent.rgt 
        and parent.id != child.id
        and parent.id = [ID];
    

    我们在这里所做的是为子表和父表创建一个别名,然后找到适合给定父节点之间的子节点。 parent.id != child.id 去掉了输出中的冗余条目。

    【讨论】:

    • 这不符合 op 的要求:我需要找到它的所有直系子女(不是孙子女
    【解决方案3】:

    为了指定和区分叶节点,请将它们保持为 left=right。这改变了两件事:

    1. 叶子很容易辨认。
    2. 进行插入时,您将添加 只有一个值(左侧 > 新叶子,就在 >= 叶子的位置)。

    【讨论】:

    • 我看不出left=rightleft=right-1 好多少,至少不足以打破嵌套集合设计的原则。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2019-10-11
    • 1970-01-01
    相关资源
    最近更新 更多