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

PHP实现层级表中子节点值汇总至父节点的技术求助

PHP计算层级数组中子节点数值总和并赋值给父节点

问题背景

现有如下数据库表结构及数据:

kia_idkia_namevalueparent_id
1ac service0
2hil0
3dispatch1
4tat main13.33
5tat air10.13
6sla comp11.72
7sla serv2
8slb9.97

需要生成带total_value_from_child列的HTML表格,该列的值为当前节点所有子节点(包括深层子节点)的value总和,最终效果如下:

kia_idkia_namevalueparent_idtotal_value_from_child
1ac service023.4
3dispatch123.4
4tat main13.33
5tat air10.13
2hil021.6
6sla comp11.72
7sla serv29.9
8slb9.97

解决方案

我们可以通过构建树状结构 + 递归计算子节点总和的方式来实现,具体步骤如下:

1. 从数据库获取数据

首先连接数据库,把所有数据读取到一个数组中(这里以PDO为例,你也可以用mysqli):

// 数据库连接配置
$host = 'localhost';
$dbname = 'your_db_name';
$username = 'your_username';
$password = 'your_password';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 查询所有数据
    $stmt = $pdo->query("SELECT kia_id, kia_name, value, parent_id FROM your_table_name");
    $data = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // 把value转换为数值类型,空值转为0
    foreach ($data as &$item) {
        $item['value'] = empty($item['value']) ? 0 : (float)$item['value'];
        $item['total_value_from_child'] = ''; // 初始化总和字段
    }
} catch(PDOException $e) {
    die("数据库连接失败: " . $e->getMessage());
}

2. 构建树状层级结构

把扁平的数组转换成以parent_id为分组的结构,方便后续递归遍历:

// 构建节点映射表,方便快速查找节点
$nodes = [];
foreach ($data as $item) {
    $nodes[$item['kia_id']] = $item;
    $nodes[$item['kia_id']]['children'] = []; // 初始化子节点数组
}

// 构建树状结构
$tree = [];
foreach ($data as $item) {
    if ($item['parent_id'] == 0) {
        $tree[] = &$nodes[$item['kia_id']];
    } else {
        $nodes[$item['parent_id']]['children'][] = &$nodes[$item['kia_id']];
    }
}

3. 递归计算子节点总和

编写一个递归函数,遍历每个节点,计算其所有子节点的value总和,并赋值给当前节点的total_value_from_child:

function calculateChildTotal(&$node) {
    $total = 0;
    // 遍历子节点
    foreach ($node['children'] as &$child) {
        // 递归计算子节点的子节点总和
        $total += calculateChildTotal($child);
        // 加上当前子节点的value
        $total += $child['value'];
    }
    // 如果总和大于0,赋值给total_value_from_child,否则留空
    if ($total > 0) {
        $node['total_value_from_child'] = number_format($total, 1); // 保留1位小数
    }
    return $total;
}

// 遍历根节点(parent_id=0的节点),触发递归计算
foreach ($tree as &$rootNode) {
    calculateChildTotal($rootNode);
}

4. 生成HTML表格

最后遍历树状结构,按层级输出HTML表格,子节点可以添加缩进以体现层级关系:

// 递归生成表格行
function generateTableRows($nodes, $indent = 0) {
    $rows = '';
    $indentStr = str_repeat(' ', $indent * 4); // 每层缩进4个空格
    foreach ($nodes as $node) {
        $rows .= "<tr>
            <td>{$node['kia_id']}</td>
            <td>{$indentStr}{$node['kia_name']}</td>
            <td>" . ($node['value'] > 0 ? $node['value'] : '') . "</td>
            <td>{$node['parent_id']}</td>
            <td>{$node['total_value_from_child']}</td>
        </tr>";
        // 递归生成子节点的行
        if (!empty($node['children'])) {
            $rows .= generateTableRows($node['children'], $indent + 1);
        }
    }
    return $rows;
}

// 输出完整的HTML表格
echo "<table border='1' cellpadding='8' cellspacing='0'>
    <thead>
        <tr>
            <th>kia_id</th>
            <th>kia_name</th>
            <th>value</th>
            <th>parent_id</th>
            <th>total_value_from_child</th>
        </tr>
    </thead>
    <tbody>
        " . generateTableRows($tree) . "
    </tbody>
</table>";

代码说明

  • 我们先把数据库数据转换成树状结构,方便层级遍历;
  • 递归函数calculateChildTotal会深度优先遍历每个节点,累加所有子节点的value(包括深层子节点);
  • 生成表格时通过缩进直观体现层级关系,和你期望的输出格式一致;
  • 空的value会被转为0参与计算,最终总和保留1位小数,符合示例中的数值格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:38:01