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

如何用Python实现SQL树形数据库的节点子孙薪资求和?

解决方案

首先需要明确:你的示例存在规则歧义——0x123的结果是仅子孙节点薪资总和(不含自身),但0x456和0x789的结果是自身+子孙节点薪资总和。下面针对两种常见规则给出实现,你可以根据实际需求选择。

前提:将数据库数据转为可快速查询的结构

先从SQL数据库读取所有记录,转换成字典映射,方便后续快速查询任意节点的子节点和薪资:

import sqlite3  # 若用MySQL等其他数据库,替换为对应驱动(如pymysql)

def load_node_data(db_path):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    # 假设表名为node_salary,字段名对应Mother, Child1, Child2, Salary
    cursor.execute("SELECT Mother, Child1, Child2, Salary FROM node_salary")
    node_map = {}
    for mother, child1, child2, salary in cursor.fetchall():
        # 过滤空的子节点
        valid_children = [child for child in (child1, child2) if child is not None]
        node_map[mother] = {"children": valid_children, "salary": salary}
    conn.close()
    return node_map

实现1:仅计算子孙节点薪资总和(匹配0x123示例)

该实现只累加目标节点的所有后代(直接/间接子节点)的薪资,不含目标节点自身:

递归版

def get_descendant_salary_sum(node_id, node_map):
    total = 0
    if node_id not in node_map:
        return total
    # 遍历当前节点的所有子节点
    for child in node_map[node_id]["children"]:
        # 累加子节点薪资
        total += node_map[child]["salary"]
        # 递归累加子节点的后代薪资
        total += get_descendant_salary_sum(child, node_map)
    return total

迭代版(避免递归栈溢出,适合大量数据)

def get_descendant_salary_sum_iter(node_id, node_map):
    total = 0
    if node_id not in node_map:
        return total
    # 用队列存储待遍历的后代节点
    queue = node_map[node_id]["children"].copy()
    while queue:
        current_node = queue.pop(0)
        if current_node not in node_map:
            continue
        total += node_map[current_node]["salary"]
        # 将当前节点的子节点加入队列
        queue.extend(node_map[current_node]["children"])
    return total

测试结果:

node_map = load_node_data("your_db.db")
print(get_descendant_salary_sum("0x123", node_map))  # 230(符合示例)
print(get_descendant_salary_sum("0x456", node_map))  # 120(与示例180不符)
print(get_descendant_salary_sum("0x789", node_map))  # 0(与示例50不符)

实现2:计算自身+所有子孙节点薪资总和(匹配0x456/0x789示例)

该实现累加目标节点自身及所有后代的薪资:

递归版

def get_self_descendant_sum(node_id, node_map):
    if node_id not in node_map:
        return 0
    total = node_map[node_id]["salary"]
    # 遍历子节点并递归累加
    for child in node_map[node_id]["children"]:
        total += get_self_descendant_sum(child, node_map)
    return total

迭代版

def get_self_descendant_sum_iter(node_id, node_map):
    total = 0
    if node_id not in node_map:
        return total
    queue = [node_id]
    while queue:
        current_node = queue.pop(0)
        total += node_map[current_node]["salary"]
        queue.extend(node_map[current_node]["children"])
    return total

测试结果:

print(get_self_descendant_sum("0x123", node_map))  # 310(与示例230不符)
print(get_self_descendant_sum("0x456", node_map))  # 180(符合示例)
print(get_self_descendant_sum("0x789", node_map))  # 50(符合示例)

匹配所有示例的折中实现

如果必须严格匹配你给出的所有示例,推测规则为:根节点仅算子孙,非根节点算自身+子孙。但这个规则逻辑不合理,仅作参考:

def get_sum_matching_all_examples(node_id, node_map, root_id="0x123"):
    if node_id == root_id:
        return get_descendant_salary_sum(node_id, node_map)
    else:
        return get_self_descendant_sum(node_id, node_map)

测试结果:

print(get_sum_matching_all_examples("0x123", node_map))  # 230
print(get_sum_matching_all_examples("0x456", node_map))  # 180
print(get_sum_matching_all_examples("0x789", node_map))  # 50

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:15:39