Heim >Backend-Entwicklung >PHP-Tutorial >请教 预排序遍历树算法(非递归无限极分类算法) ,删除一个分支节点和它所有的子节点问题

请教 预排序遍历树算法(非递归无限极分类算法) ,删除一个分支节点和它所有的子节点问题

WBOY
WBOYOriginal
2016-06-23 13:45:201449Durchsuche




删除一个分支节点和它所有的子节点,从网上看到一段代码,发现这个是错的,
请教一下,这个怎么写SQL,谢谢!


回复讨论(解决方案)

http://blog.163.com/023_dns/blog/static/118727366201271492450798/ 参考的是这里的,想让删除后,所有的节点左右编号还依然正确

描述详细点,业务需求是什么,语法错还是逻辑错?

它的这个方法 实现不了, 删除节点及所有子节点。


我是用http://www.111cn.net/phper/21/d2ae4d2906dcb71cda0dfdbb5bf13857.htm  这个表试的

INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (42, 'Food', 1, 18);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (1, 'Fruit', 2, 11);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (3, 'Red', 3, 6);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (4, 'Cherry', 4, 5);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (5, 'Yellow', 7, 10);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (6, 'Banana', 8, 9);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (7, 'Meat', 12, 17);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (8, 'Beef', 13, 14);INSERT INTO `food` (`id`, `name`, `lft`, `rgt`) VALUES (9, 'Pork', 15, 16);

delete from food where lft>=当前节点的lft AND rgt <= 当前节点的rgt
 

UPDATE nested_category SET lft = lft - @myWidth WHERE lft >  @myRight
应该为
UPDATE nested_category SET lft = lft - @myWidth WHERE lft >  @myLeft

delete from food where lft>=当前节点的lft AND rgt <= 当前节点的rgt
 



这种改法 应该是删除节点(没有子节点)  可以。


但是现在要是删除 节点及子节点 ,节点本身有子节点儿,就不正确了

刚发错了,应该是七楼错了


UPDATE nested_category SET lft = lft - @myWidth WHERE lft >  @myRight
应该为
UPDATE nested_category SET lft = lft - @myWidth WHERE lft >  @myLeft



这种改法 应该是删除节点(没有子节点)  可以。


但是现在要是删除 节点及子节点 ,节点本身有子节点儿,就不正确了 

CREATE temporary TABLE tree ( id INTEGER , parent INTEGER NOT NULL DEFAULT '0', title VARCHAR(20) , leftnum INTEGER NOT NULL DEFAULT '0', rightnum INTEGER NOT NULL DEFAULT '0' );INSERT INTO tree VALUES ('1', '0', 'Food', '1', '18');INSERT INTO tree VALUES ('2', '1', 'Fruit', '2', '11');INSERT INTO tree VALUES ('3', '2', 'Red', '3', '6');INSERT INTO tree VALUES ('4', '3', 'Cherry', '4', '5');INSERT INTO tree VALUES ('5', '2', 'Yellow', '7', '10');INSERT INTO tree VALUES ('6', '5', 'Banana', '8', '9');INSERT INTO tree VALUES ('7', '1', 'Meat', '12', '17');INSERT INTO tree VALUES ('8', '7', 'Beef', '13', '14');INSERT INTO tree VALUES ('9', '7', 'Pork', '15', '16');select * from tree;
id parent title leftnum rightnum 1  0      Food   1       18 2  1      Fruit  2       11 3  2      Red    3       6 4  3      Cherry 4       5 5  2      Yellow 7       10 6  5      Banana 8       9 7  1      Meat   12      17 8  7      Beef   13      14 9  7      Pork   15      16 

select @myLeft:=leftnum, @myRight:=rightnum, @myWidth:=rightnum-leftnum+1from tree where id=5;delete from tree where leftnum between @myLeft and @myRight;select * from tree;
id parent title leftnum rightnum 1  0      Food   1       18 2  1      Fruit  2       11 3  2      Red    3       6 4  3      Cherry 4       5 7  1      Meat   12      17 8  7      Beef   13      14 9  7      Pork   15      16 

update tree set rightnum=rightnum-@myWidth where rightnum>@myRight;update tree set leftnum=leftnum-@myWidth where leftnum>@myLeft;select * from tree;
id parent title leftnum rightnum 1  0      Food   1       18 2  1      Fruit  2       11 3  2      Red    3       6 4  3      Cherry 4       5 7  1      Meat   8       13 8  7      Beef   9       10 9  7      Pork   11      12 

自己看,不会错的!

UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myLeft
是修改所有大于被删节点的左值的节点,如果和被删节点的右值进行比较那才是大错特错了

对于一个节点,凡是左值大于该节点的左值、右值小于该节点的右值的节点,都是该节点的子节点

[/code]
自己看,不会错的!




再请教一下,我用的存储过程,转的是 当前节点的左边序号和右边序号 和当前节点名。
DELIMITER //
CREATE PROCEDURE deleteallzijiedian(IN lpid int,IN rpid int,IN zijidianname VARCHAR(10))
begin

DELETE FROM Food WHERE lft BETWEEN lpid AND rpid;
UPDATE Food SET rgt = rgt - ( rgt - lft + 1) WHERE rgt > rpid;
UPDATE Food SET lft = lft - ( rgt - lft + 1) WHERE lft > lpid;

END
//
DELIMITER ;



CALL deleteallzijiedian(3,6,'Red');

我这里哪错了吗?

将左右值作为参数传递是错误的,因为每个节点的左右值是会变的(插入、删除、修改都可能会改变)
所以你主贴中读取左右值到用户变量的做法是正确的

 



刚又发现个问题,你粘的最后结果,Fruit 的右边值正确的应该是7, 你的是11,另外,Food 右边的现在变成14了吧, 这些能处理吗?
id parent title leftnum rightnum 
1  0      Food   1        18 
2  1      Fruit  2        11 
3  2      Red    3       6 
4  3      Cherry 4       5 
7  1      Meat   8       13 
8  7      Beef   9       10 
9  7      Pork   11      12 

id parent title leftnum rightnum 
1 0 Food 1 14 
2 1 Fruit 2 7 
3 2 Red 3 6 
4 3 Cherry 4 5 
7 1 Meat 8 13 
8 7 Beef 9 10 
9 7 Pork 11 12 
是我为了少调整格式,复制了前面的结果



 多谢了!
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn