在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,
(SELECT @ids := GROUP_CONCAT(parent_id) FROM sys_dept WHERE FIND_IN_SET(id, @ids)) AS cids
FROM sys_dept, (SELECT @ids := #{id}) b
WHERE @ids IS NOT NULL
) a, sys_dept b
WHERE FIND_IN_SET(b.id, a._ids) OR FIND_IN_SET(b.id, a.cids)
ORDER BY id;
使用时,将 sys_dept
替换为你自己的表名,并将 #{id}
替换为具体的子节点ID。
以上就是在MySQL中递归查询父节点和子节点的几种常用方法。你可以根据实际需求修改表名和ID号,从而实现相应的递归查询。