You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP递归遍历MySQL二叉树表并统计指定根节点下各Rank人数

递归遍历二叉树统计指定根节点下各Rank人数(PHP+MySQL实现)

假设的MySQL表结构

先假设你的二叉树表结构如下(请根据实际表结构调整字段名):

CREATE TABLE tree_nodes (
    id INT PRIMARY KEY AUTO_INCREMENT,
    parent_id INT COMMENT '父节点ID,根节点可设为0或NULL',
    name VARCHAR(50) NOT NULL COMMENT '节点名称',
    rank INT COMMENT '用户等级',
    FOREIGN KEY (parent_id) REFERENCES tree_nodes(id)
);

PHP实现代码

使用MySQL递归CTE(Common Table Expression)高效查询所有子节点,再通过PHP补全指定Rank的统计结果:

<?php
// 数据库连接参数
$dbConfig = [
    'host' => 'localhost',
    'dbname' => 'your_db_name',
    'username' => 'your_username',
    'password' => 'your_password'
];

try {
    // 初始化PDO连接
    $pdo = new PDO(
        "mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']};charset=utf8mb4",
        $dbConfig['username'],
        $dbConfig['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );

    // 目标根节点ID
    $rootId = 2;

    // 获取根节点名称
    $getNameStmt = $pdo->prepare("SELECT name FROM tree_nodes WHERE id = ?");
    $getNameStmt->execute([$rootId]);
    $rootName = $getNameStmt->fetchColumn();
    
    if (!$rootName) {
        echo "指定的根节点不存在";
        exit;
    }

    // 递归查询根节点下所有子节点的Rank数据
    $recursiveSql = "
        WITH RECURSIVE node_hierarchy AS (
            -- 初始查询:根节点的直接子节点
            SELECT id, rank FROM tree_nodes WHERE parent_id = ?
            UNION ALL
            -- 递归查询:所有后代节点
            SELECT tn.id, tn.rank 
            FROM tree_nodes tn
            JOIN node_hierarchy nh ON tn.parent_id = nh.id
        )
        SELECT rank, COUNT(*) AS user_count 
        FROM node_hierarchy 
        WHERE rank IS NOT NULL -- 过滤无等级的节点
        GROUP BY rank 
        ORDER BY rank;
    ";

    $statsStmt = $pdo->prepare($recursiveSql);
    $statsStmt->execute([$rootId]);
    // 转换为Rank为键、人数为值的数组
    $rankStats = $statsStmt->fetchAll(PDO::FETCH_KEY_PAIR);

    // 补全Rank 1-4的统计(无数据则设为0)
    $targetRanks = [1, 2, 3, 4];
    $finalStats = [];
    foreach ($targetRanks as $rank) {
        $finalStats[$rank] = $rankStats[$rank] ?? 0;
    }

    // 输出结果
    echo "Root > {$rootName}\n";
    foreach ($finalStats as $rank => $count) {
        echo "Rank {$rank}用户数:{$count}\n";
    }

} catch (PDOException $e) {
    die("数据库操作失败:" . $e->getMessage());
}
?>

代码说明

  1. 递归CTE查询:通过WITH RECURSIVE语法一次性获取根节点下所有后代节点,比PHP递归查询数据库效率更高。
  2. 结果补全:确保Rank 1到4的统计都存在,即使某个Rank没有用户也显示0。
  3. 灵活调整:如果需要包含根节点自身的统计,只需将CTE的初始查询改为SELECT id, rank FROM tree_nodes WHERE id = ?。

内容的提问来源于stack exchange,提问作者Mudassar Akram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:41:04