mysql 通过当前父节点查询所有的子节点

这篇博客探讨了如何使用SQL查询获取具有层级关系的数据,特别是在t_department表中,根据平台类型和状态筛选部门,并进行递归查询以获取指定ID的子级部门。两种查询方式分别展示了不包含和包含自身的情况,且都限制在三级以内。这些查询对于理解和操作层级结构数据至关重要。
      SELECT rd.*
       FROM (SELECT * FROM t_department WHERE parent_id IS NOT NULL and 
      type=#{platformType} and status=0 ) rd,
      (SELECT @pid :=#{id}) pd
       WHERE FIND_IN_SET(parent_id, @pid) > 0
      AND @pid := concat(@pid, ',', id)
    //不包含自己 (注意只能查询三级)

    SELECT rd.*
       FROM (SELECT * FROM t_department WHERE parent_id IS NOT NULL and 
      type=#{platformType} and status=0 ) rd,
      (SELECT @pid :=#{id}) pd
       WHERE FIND_IN_SET(parent_id, @pid) > 0
      AND @pid := concat(@pid, ',', id)
     union select * from t_department  where FIND_IN_SET(id,@pid) > 0;(包含自己 *注意只能查询三级)


//没有层级限制

SELECT DATA.* FROM(

        SELECT

        @ids as _ids,

        ( SELECT @ids := GROUP_CONCAT(id)

        FROM t_department

        WHERE FIND_IN_SET(parent_id, @ids)

        ) as cids,

        @l := @l+1 as level

        FROM t_department,

        (SELECT @ids :=#{id}, @l := 0 ) b

        WHERE @ids IS NOT NULL

        ) id, t_epartment DATA

        WHERE FIND_IN_SET(DATA.id, ID._ids)
       
        ORDER BY  id

 

MySQL 中,由于早期版本(如 5.0、5.5)并不支持递归查询(如 `WITH RECURSIVE` 语法),因此在实现树形结构中根据子节点向上递归查找父节点时,通常需要借助存储过程或函数来模拟递归逻辑。 ### 使用存储过程或函数递归查询父节点 以下是一个通过函数实现的示例,用于根据子节点 ID 递归查询所有父节点,直到根节点(假设树形结构表为 `address`,包含字段 `id` 和 `parent_id`): ```sql DELIMITER $$ CREATE FUNCTION get_parent_nodes(son_id BIGINT) RETURNS VARCHAR(2000) BEGIN DECLARE finalVar VARCHAR(2000); DECLARE tempVar BIGINT; SET finalVar = '$'; SET tempVar = son_id; WHILE tempVar <> 0 DO SET finalVar = CONCAT(finalVar, ',', tempVar); SELECT t.parent_id INTO tempVar FROM address t WHERE t.id = tempVar; END WHILE; RETURN finalVar; END$$ DELIMITER ; ``` 调用该函数时,传入子节点 ID 即可获取从该节点到根节点的所有路径: ```sql SELECT get_parent_nodes(123) AS parent_path; ``` 该函数将返回一个以逗号分隔的节点路径字符串,包含当前子节点及其所有父节点,直到根节点(`parent_id = 0`)[^2]。 ### 使用临时变量模拟递归(适用于有限层级) 如果树的层级较浅,也可以使用多个 `JOIN` 操作来手动模拟递归查询,例如查找最多五层的父节点: ```sql SELECT t1.name AS level1, t2.name AS level2, t3.name AS level3, t4.name AS level4, t5.name AS level5 FROM address t1 LEFT JOIN address t2 ON t1.parent_id = t2.id LEFT JOIN address t3 ON t2.parent_id = t3.id LEFT JOIN address t4 ON t3.parent_id = t4.id LEFT JOIN address t5 ON t4.parent_id = t5.id WHERE t1.id = 123; ``` 此方法适用于层级固定或较浅的场景,但不适用于深度不确定的树结构。 ### MySQL 8.0 及以上版本支持递归查询MySQL 8.0 及以上版本中,可以使用 `WITH RECURSIVE` 语法实现真正的递归查询。例如,查询某个子节点的所有祖先节点: ```sql WITH RECURSIVE parent_tree AS ( SELECT id, parent_id, name FROM address WHERE id = 123 UNION ALL SELECT a.id, a.parent_id, a.name FROM address a INNER JOIN parent_tree p ON a.id = p.parent_id ) SELECT * FROM parent_tree; ``` 该查询会从指定的子节点开始,逐层向上查找父节点,直到根节点为止,适用于任意深度的树形结构[^1]。 ### 总结 - 对于 MySQL 5.x 版本,需通过函数或存储过程模拟递归查询父节点。 - 对于 MySQL 8.0 及以上版本,推荐使用 `WITH RECURSIVE` 实现更简洁高效的递归查询。 - 若层级有限,也可以通过多次 `JOIN` 查询父节点链。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值