MySQL 中递归查询父子节点是一个常见需求,无论是从父节点查询所有子节点,还是从子节点查询所有父节点,都需要合理构建SQL查询语句。以下是几种常用的递归查询方法,供参考。

根据父节点递归查询所有子节点

以下SQL语句可以根据父节点递归查询所有子节点:

SELECT t3.*
FROM (SELECT t1.*,
             IF (FIND_IN_SET(parent_id, @pids) > 0, @pids := CONCAT(@pids, ',', id), '0') AS ischild
      FROM (SELECT t.id, t.parent_id, t.NAME
            FROM t_parent AS t
            ORDER BY t.id ASC) t1,
           (SELECT @pids := '0') t2) t3
WHERE ischild != '0';

在实际使用时,需要将 t_parent 替换为你自己的表名, @pids := '0' 中的 0 是你要查询的父ID号,不包含自身。

另一个查询例子是:

SELECT rd.* 
FROM (SELECT * FROM sys_dict WHERE parent_id IS NOT NULL) rd,
     (SELECT @pid := '1') pd 
WHERE FIND_IN_SET(parent_id, @pid) > 0 
  AND @pid := CONCAT(@pid, ',', id)
UNION 
SELECT * FROM sys_dict WHERE id = @pid;

这段SQL语句的关键是 @pid := '1' ,它是要查询的父ID号,且包含自身。如果你不希望查询结果包含自身,可以去掉 UNION 部分。

通过子ID递归查询父节点

如果你需要从子节点递归查询到父节点(即向上查找父节点到根节点),可以使用以下SQL语句:

SELECT t3.*
FROM (SELECT t1.*,
             IF (FIND_IN_SET(id, @ids) > 0, @ids := CONCAT(parent_id, ',', @ids), '0') AS isparent
      FROM (SELECT t.id, t.parent_id, t.NAME
            FROM t_parent AS t
            ORDER BY t.id DESC) t1,
           (SELECT @ids := '111') t2) t3
WHERE t3.isparent != '0';

在这个例子中,将 t_parent 替换为你自己的表名, @ids := '111' 中的 111 是你要查询的子ID号。与查询子节点不同的是,这里使用 ORDER BY t.id DESC 来从子节点向上递归查询。

另一种方式是:

SELECT b.id, b.parent_id, b.name
FROM (
    SELECT @ids AS _ids,