【问题标题】:Nested set - can't move node to last parent嵌套集 - 无法将节点移动到最后一个父节点
【发布时间】:2013-10-07 17:23:26
【问题描述】:

我目前面临一个无法解决的问题。我为所有类别使用嵌套集,当我需要移动它们时,会出现某种错误。 我的问题是,如果我想移动一个节点 - 例如ID=2从“顶层”改为underlay ID=1,将ID=1上的Rgt=1和Lft=4+ID=2上的Rgt=2和Lft=3,就可以了。

问题是,如果我尝试将 ID=2 的节点移动到最后一个节点 - ID=5,Rgt=9,Lft=10,那么它真的毁了我的表 - 我看不到什么mySQL 查询出错了 - 希望您能帮忙...

我的桌子 WHEN I START 是这样的:

ID | Name        | Rgt  | Lft | ParentID
---+-------------+------+-----+---------
1  | Trousers    | 1    | 2   | 0
---+-------------+------+-----+---------
2  | Jeans       | 3    | 4   | 0
---+-------------+------+-----+---------
3  | Tops        | 5    | 6   | 0
---+-------------+------+-----+---------
4  | T-shirts    | 7    | 8   | 0
---+-------------+------+-----+---------
5  | Shirts      | 9    | 10  | 0
---+-------------+------+-----+---------

我的查询是这样的:

SELECT
    @node_id := '2',
    @node_pos_left := '3',
    @node_pos_right := '4',
    @parent_id := '5',
    @parent_pos_right := '10';
SELECT
    @node_size := @node_pos_right - @node_pos_left + 1; 



UPDATE ss_C_Categories
SET Lft = 0-(Lft), `Rgt` = 0-(Rgt)
WHERE Lft >= @node_pos_left AND Rgt <= @node_pos_right;



UPDATE ss_C_Categories
SET Lft = Lft - @node_size
WHERE Lft > @node_pos_right;

UPDATE ss_C_Categories
SET Rgt = Rgt - @node_size
WHERE Rgt > @node_pos_right;



UPDATE ss_C_Categories
SET Lft = Lft + @node_size
WHERE Lft >= IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_size, @parent_pos_right);

UPDATE ss_C_Categories
SET Rgt = Rgt + @node_size
WHERE Rgt >= IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_size, @parent_pos_right);



UPDATE ss_C_Categories
SET
    Lft = 0-(Lft)+IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_pos_right - 1, @parent_pos_right - @node_pos_right - 1 + @node_size),
    Rgt = 0-(Rgt)+IF(@parent_pos_right > @node_pos_right, @parent_pos_right - @node_pos_right - 1, @parent_pos_right - @node_pos_right - 1 + @node_size)
WHERE Lft <= 0-@node_pos_left AND Rgt >= 0-@node_pos_right;

UPDATE ss_C_Categories
SET ParentID = @parent_id
WHERE CategoryID = @node_id;

执行查询后,我的表格如下所示:

ID | Name        | Rgt  | Lft | ParentID
---+-------------+------+-----+---------
1  | Trousers    | 1    | 2   | 0
---+-------------+------+-----+---------
2  | Jeans       | 10   | 11  | 5
---+-------------+------+-----+---------
3  | Tops        | 5    | 6   | 0
---+-------------+------+-----+---------
4  | T-shirts    | 3    | 4   | 0
---+-------------+------+-----+---------
5  | Shirts      | 7    | 8   | 0
---+-------------+------+-----+---------

我用这个答案作为我如何做这些动作的灵感:https://stackoverflow.com/a/1274175/1308905

【问题讨论】:

    标签: mysql nested-sets


    【解决方案1】:

    好吧,现在我在很多图纸的帮助下制作了自己的 MySQL,我认为这应该是要走的路,如果(并且仅在这种情况下): - 您要将节点从一个父节点移动到另一个父节点。换句话说 - 不要使用它来移动到“顶级”(尚未)。我还没有测试过。

    尽管将子树移动到另一个父级应该是防弹的(无论新父级处于什么级别)。 :-)

    $query = $this->prepare("           
        SELECT
            @node_id := :nodeID, #id of the node, you're moving.
            @node_pos_left := :nodeLeft, #left value of the node, you're moving
            @node_pos_right := :nodeRight, #right value of the node, you're moving
            @parent_id := :parentID, #id of the parent node, you're moving to
    
            @parent_pos_right := :parentRight; #right value of the parent node, you're moving to.
    
        SELECT
            @node_size := @node_pos_right - @node_pos_left + 1; 
    
        SELECT
            @node_id := :nodeID, 
            @node_pos_left := :nodeLeft, 
            @node_pos_right := :nodeRight, 
            @parent_id := :parentID, 
    
            @parent_pos_right := :parentRight; 
        SELECT
            @node_size := @node_pos_right - @node_pos_left + 1; 
    
    
        UPDATE ss_C_Categories
        SET Lft = 0-(Lft), Rgt = 0-(Rgt)
        WHERE Lft >= @node_pos_left AND Rgt <= @node_pos_right;
    
    
    
        UPDATE ss_C_Categories
        SET Lft = Lft + @node_size
        WHERE Lft >= @parent_pos_right;
    
        UPDATE ss_C_Categories
        SET Rgt = Rgt + @node_size
        WHERE Rgt >= @parent_pos_right;
    
    
        UPDATE ss_C_Categories
        SET Lft = 0 - (Lft) + (@parent_pos_right - @node_pos_right + 1)
        WHERE Lft < 0;
    
        UPDATE ss_C_Categories
        SET Rgt = 0 - (Rgt) + (@parent_pos_right - @node_pos_right + 1)
        WHERE Rgt < 0;
    
    
    
        UPDATE ss_C_Categories
        SET Lft = Lft - @node_size
        WHERE 
            Lft > @node_pos_right;
    
    
        UPDATE ss_C_Categories
        SET Rgt = Rgt - @node_size
        WHERE 
            Rgt > @node_pos_right;
    
    
    
        UPDATE
            ".DB_PREFIX."C_Categories
        SET
            CategoryName = :name,
            MetaTag = :metatag,
            ParentID = @parent_id,
            Description = :desc
        WHERE
            CategoryID = @node_id
        ORDER BY
            CategoryID desc
        LIMIT 1;
    ");
    
    
    $params = array(
        array('nodeLeft', $nodeLeft, 'INT'),
        array('nodeRight', $nodeRight, 'INT'),
        array('nodeID', $nodeID, 'INT'),
        array('parentRight', $parentRight, 'INT'),
        array('parentID', $parentID, 'INT'),
        array('name', $data['name'], 'STR'),
        array('metatag', $data['metatag'], 'STR'),
        array('desc', $data['description'], 'STR')
    );
    
    $this->exec($query, $params);
    

    再次从问题中的链接中获得灵感。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2010-12-08
      • 2021-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多