PHP+MySQL实现无限层级推荐左右分支人数统计需求咨询
统计用户推荐分支人数的PHP实现方案
作为PHP新手,别担心,我会一步步帮你搞定这个需求。首先咱们明确核心逻辑:因为推荐层级是无限延伸的,所以得用递归查询遍历所有推荐分支,再区分出左右分支(也就是你例子里A的直接推荐人B、C各自延伸出的线路)。
前提说明
假设你的user表有自增主键id(如果没有建议补上,方便排序确定左右分支;不想加的话,也可以用用户创建时间、username排序来替代)。咱们默认按id从小到大排序,第一个直接推荐人对应左分支,第二个对应右分支。
另外,MySQL 8.0及以上版本支持CTE(公共表表达式),用它做递归查询比PHP写递归函数效率高很多,所以优先用这个方案。
完整代码实现
<?php // 数据库配置,替换成你的实际信息 $dbHost = 'localhost'; $dbName = 'your_database'; $dbUser = 'your_username'; $dbPass = 'your_password'; try { // 初始化PDO连接(新手推荐用PDO,比mysqli更安全易维护) $pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 要统计的目标用户名,比如例子里的'A' $targetUser = 'A'; // 第一步:获取目标用户的直接推荐人,按id排序确定左右分支 $directStmt = $pdo->prepare(" SELECT username, id FROM user WHERE upline = :target ORDER BY id ASC "); $directStmt->execute([':target' => $targetUser]); $directReferrals = $directStmt->fetchAll(PDO::FETCH_ASSOC); // 初始化分支统计结果 $branchStats = [ 'left' => 0, 'right' => 0, 'total' => 0 ]; // 第二步:递归统计每个分支的总人数(包含直接推荐人本身) if (!empty($directReferrals)) { // 处理左分支(第一个直接推荐人) if (isset($directReferrals[0])) { $leftUser = $directReferrals[0]['username']; $leftStmt = $pdo->prepare(" WITH RECURSIVE referral_tree AS ( SELECT username FROM user WHERE username = :user UNION ALL SELECT u.username FROM user u JOIN referral_tree rt ON u.upline = rt.username ) SELECT COUNT(*) as count FROM referral_tree "); $leftStmt->execute([':user' => $leftUser]); $branchStats['left'] = $leftStmt->fetch(PDO::FETCH_ASSOC)['count']; } // 处理右分支(第二个直接推荐人) if (isset($directReferrals[1])) { $rightUser = $directReferrals[1]['username']; $rightStmt = $pdo->prepare(" WITH RECURSIVE referral_tree AS ( SELECT username FROM user WHERE username = :user UNION ALL SELECT u.username FROM user u JOIN referral_tree rt ON u.upline = rt.username ) SELECT COUNT(*) as count FROM referral_tree "); $rightStmt->execute([':user' => $rightUser]); $branchStats['right'] = $rightStmt->fetch(PDO::FETCH_ASSOC)['count']; } // 总人数 = 左分支 + 右分支(如果有更多直接推荐人,可扩展逻辑) $branchStats['total'] = $branchStats['left'] + $branchStats['right']; } // 输出统计结果 echo "用户{$targetUser}的推荐统计:\n"; echo "左分支人数:{$branchStats['left']}\n"; echo "右分支人数:{$branchStats['right']}\n"; echo "总推荐人数:{$branchStats['total']}\n"; } catch(PDOException $e) { die("数据库操作出错: " . $e->getMessage()); } ?>
代码细节解释
- 数据库连接:用PDO做数据库连接,自带错误处理,新手更容易排查问题。
- 获取直接推荐人:先查出目标用户的所有直接推荐人,按
id排序来确定左右分支的起点。 - CTE递归查询:
WITH RECURSIVE语法会先选中分支起点用户,然后递归遍历所有下级推荐人,最后统计该分支的总人数。 - 结果输出:清晰展示左、右分支和总推荐人数,方便你验证结果。
适配你的例子
在你给出的场景里:
- A的直接推荐人是B(左)和C(右)
- 左分支B的下属有D、E,加上B自己总3人,和你描述的一致
- 右分支C的下属有F、G、H,加上C自己总4人
- 总人数3+4=7,如果你不想把直接推荐人本身算进去,只需要把CTE的初始查询改成
SELECT username FROM user WHERE upline = :user,就能统计所有间接推荐人了。
如果你的MySQL版本低于8.0(不支持CTE),可以用PHP递归函数实现,需要的话我再给你写对应版本的代码。
注意事项
- 确保
upline字段的存储没有拼写错误,比如B的upline必须准确是'A',否则递归会出错。 - 给
upline字段加索引,数据量大时能大幅提升查询速度。 - 如果目标用户有超过2个直接推荐人,可以扩展代码,比如新增「其他分支」的统计逻辑。
内容的提问来源于stack exchange,提问作者Powhattan
相关产品推荐
相关产品推荐

