How to find all IDs of children recursively?

后端 未结 6 612
死守一世寂寞
死守一世寂寞 2020-12-05 07:58

I would like to get all IDs from children in a tree with MySQL only.

I have a table like this:

ID parent_id name
1  0         cat1
2  1         subca         


        
6条回答
  •  被撕碎了的回忆
    2020-12-05 08:51

    Here is a simple single-query MySql-solution:

    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 := ) temp1
    ) temp2
    

    Just substitute with the parent element's ID.

    This will return a string with the IDs of all descendants of the element with ID = , separated by ,. If you would rather have multiple rows returned, with one descendant on each row, you can use something like this:

    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 := ) temp1
       ) temp2
    ))
    

    Including the root/parent element

    The OP asked for the children of an element, which is answered above. In some cases it might be useful to include the root/parent element in the result. Here are my suggested solutions:

    Comma-separated string of ids:

    SELECT GROUP_CONCAT(Level SEPARATOR ',') FROM (
       SELECT  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 := ) temp1
    ) temp2
    

    Multiple rows:

    SELECT *
    FROM `table_name`
    WHERE `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 := ) temp1
       ) temp2
    ))
    

提交回复
热议问题