RT 像这么一张表的级联,这时候我删除广东省的话 ,就要把广东省下面的如广州市,荔湾区,越秀区.....这些全删掉,也包括广东下面其他市和县都要删掉,想了很久、如果只是删他的下级的话、还是很容易的、一条SQL就行、但是如果要删三级呢?同事说用递归、想了很久都不会、也搜索了全网、都没有找到、有大佬知道怎么写吗、谢谢。(当然实际上不是这张表,用这张表只是觉得比较经典,大家一看就明白)
下面是一个递归查询某个 area_id 对应的所有子节点的递归函数,它会返回一个数组,然后用 IN 条件来删除,可以试试:
-- 自定义函数查询子节点
delimiter $$
create function `getChildLst`(`rootId` varchar(64)) returns varchar(1000)
BEGIN
DECLARE sTemp VARCHAR(1000);
DECLARE sTempChd VARCHAR(1000);
SET sTemp = '$';
SET sTempChd = rootId;
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp,',',sTempChd);
SELECT group_concat(area_id) INTO sTempChd FROM t_area
where FIND_IN_SET(pid,sTempChd)>0;
END WHILE;
RETURN sTemp;
END
$$
delimiter ;
说明:这是分组递归查询的函数,参数为当前顶级groupId
使用: select g2.area_id from t_area g2 where find_in_set(g2.area_ID, getChildLst(#{groupId}));
该sql可以返回此groupId和以此groupId为根节点的所有结点
我使用的是mysql,不知道你的可不可以,用我的mysql替换了你的表名,没测试,自己去测试一下可不可以。这里的select @pv := 1 中的1是父id,然后会去递归查询父id下的所有子id,包括子id的子id。
delete from area where area_id in ( select area_id
from (select * from t_area
order by area_id, parent_id) m,
(select @pv := 1 ) initialisation
where find_in_set(parent_id, @pv)
and length(@pv := concat(@pv, ',', area_id)))
我原本的写法
delete from menu where m_id in ( select m_id
from (select * from menu
order by m_fid, m_id) m,
(select @pv := 1 ) initialisation
where find_in_set(m_fid, @pv)
and length(@pv := concat(@pv, ',', m_id)))