PHP+MySQL如何查询指定节点下所有层级子节点(含自身)
查询指定用户下所有层级团队成员的可行实现
你之前的UNION SQL只写了两层关联查询,自然无法获取第三层及更深层级的子用户;编写的PHP代码存在变量覆盖、无递归遍历逻辑、重复查库的问题,运行结果不符合预期是正常的。下面提供两种可直接落地的实现方案,适配不同的环境:
方案一:MySQL 8.0及以上版本,使用递归CTE实现(推荐)
如果你的数据库版本支持递归公用表表达式(CTE),直接用单条SQL即可实现任意深度的层级查询,不需要额外写业务代码,性能最优。
以查询userid=1的全团队成员为例,SQL语句如下:
WITH RECURSIVE user_team AS ( -- 锚点成员:先查询到作为团队根的指定用户 SELECT userid, name, parent_user FROM users WHERE userid = 1 UNION ALL -- 递归成员:循环关联查询当前结果集中所有用户的直接下级,直到没有新的下级数据为止 SELECT u.userid, u.name, u.parent_user FROM users u INNER JOIN user_team ut ON u.parent_user = ut.userid ) -- 最终返回需要的字段即可 SELECT userid, name FROM user_team;
该写法会自动递归遍历所有下级层级,不管团队有3层还是10层,都能一次性返回正确结果,不需要手动拼接多层UNION。
方案二:MySQL 5.x等低版本,使用PHP递归实现
如果你的数据库版本不支持递归CTE,可以用PHP实现层级遍历,建议先一次性拉取全量用户数据在内存中处理,避免循环中反复查询数据库带来的性能损耗,代码如下:
<?php // 初始化连接参数(按你实际的数据库配置填写即可) $conn = new mysqli('数据库地址', '用户名', '密码', '库名'); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } $targetUserId = 1; // 要查询的团队根用户ID // 1. 一次性查询全量用户数据,构建上下级映射关系 $sql = $conn->prepare("SELECT userid, name, parent_user FROM users"); $sql->execute(); $result = $sql->get_result(); $userMap = []; $childMap = []; // 存储每个用户对应的直接下级ID列表 while ($row = $result->fetch_assoc()) { $userMap[$row['userid']] = $row; $childMap[$row['parent_user']][] = $row['userid']; } // 2. 递归遍历收集所有团队成员ID $teamIds = []; function getTeamMembers($rootId, $childMap, &$teamIds) { // 把当前用户加入团队列表 $teamIds[] = $rootId; // 当前用户没有下级时终止递归 if (!isset($childMap[$rootId])) { return; } // 遍历所有直接下级,递归收集他们的下属 foreach ($childMap[$rootId] as $cid) { getTeamMembers($cid, $childMap, $teamIds); } } getTeamMembers($targetUserId, $childMap, $teamIds); // 3. 组装最终结果 $teamList = []; foreach ($teamIds as $uid) { $teamList[] = [ 'userid' => $uid, 'name' => $userMap[$uid]['name'] ]; } // 打印/使用结果即可 print_r($teamList); ?>
该实现仅需要执行一次数据库查询,通过内存映射+递归遍历的方式处理层级关系,支持任意深度的上下级结构,不会出现之前只能查到两层数据的问题。
内容的提问来源于stack exchange,提问作者userdev2222
相关产品推荐
相关产品推荐

