如何递归查找子项的所有ID?

16 mysql sql database recursion nested

我想从只有MySQL的树中获取孩子们的所有ID.

我有这样一张桌子:

ID parent_id name
1  0         cat1
2  1         subcat1
3  2         sub-subcat1
4  2         sub-subcat2
5  0         cat2
Run Code Online (Sandbox Code Playgroud)

现在我试图以递归方式获取cat1(2,3,4)的所有子ID.有什么办法可以实现吗?

cle*_*tus 16

执行此操作有两种基本方法:邻接列表和嵌套列表.看一下在MySQL管理分层数据.

你有什么是邻接名单.没有办法用一个SQL语句递归抓取所有后代.如果可能的话,只需抓住它们并将它们全部映射到代码中.

嵌套集可以做你想要的,但我倾向于避免它,因为插入记录的成本很高,而且容易出错.


Mag*_*eit 7

这是一个简单的单查询MySql解决方案:

SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
   SELECT @Ids := (
       SELECT GROUP_CONCAT(`ID` SEPARATOR ',')
       FROM `table_name`
       WHERE FIND_IN_SET(`parent_id`, @Ids)
   ) Level
   FROM `table_name`
   JOIN (SELECT @Ids := <id>) temp1
) temp2
Run Code Online (Sandbox Code Playgroud)

只需替换<id>父元素即可ID.

这将返回一个带有一个字符串ID与所述元件的所有后代第ID= <id>,由分离,.如果您希望返回多行,每行有一个后代,您可以使用以下内容:

SELECT *
FROM `table_name`
WHERE FIND_IN_SET(`ID`, (
   SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
      SELECT @Ids := (
          SELECT GROUP_CONCAT(`ID` SEPARATOR ',')
          FROM `table_name`
          WHERE FIND_IN_SET(`parent_id`, @Ids)
      ) Level
      FROM `table_name`
      JOIN (SELECT @Ids := <id>) temp1
   ) temp2
))
Run Code Online (Sandbox Code Playgroud)

包括root/parent元素

OP要求一个元素的孩子,这是上面回答的.在某些情况下,在结果中包含root/parent元素可能很有用.以下是我建议的解决方案:

以逗号分隔的ID字符串:

SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
   SELECT <id> Level
   UNION
   SELECT @Ids := (
       SELECT GROUP_CONCAT(`ID` SEPARATOR ',')
       FROM `table_name`
       WHERE FIND_IN_SET(`parent_id`, @Ids)
   ) Level
   FROM `table_name`
   JOIN (SELECT @Ids := <id>) temp1
) temp2
Run Code Online (Sandbox Code Playgroud)

多行:

SELECT *
FROM `table_name`
WHERE `ID` = <id> OR FIND_IN_SET(`ID`, (
   SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
      SELECT @Ids := (
          SELECT GROUP_CONCAT(`ID` SEPARATOR ',')
          FROM `table_name`
          WHERE FIND_IN_SET(`parent_id`, @Ids)
      ) Level
      FROM `table_name`
      JOIN (SELECT @Ids := <id>) temp1
   ) temp2
))
Run Code Online (Sandbox Code Playgroud)