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

Oracle层级查询:如何计算各节点的子节点成本总和?

解决方案

方法1:递归CTE(最直观简便)

Oracle 11g及以上支持递归CTE,逻辑完全贴合需求:先计算叶子节点的CALCULATED_COST,再向上递归计算父节点的总和(直接子节点的CALCULATED_COST之和)。

WITH recursive_calc AS (
    -- 锚点:叶子节点(没有子节点的节点)
    SELECT 
        id, parent_id, label, cost,
        cost AS calculated_cost
    FROM objective
    WHERE id NOT IN (SELECT DISTINCT parent_id FROM objective WHERE parent_id IS NOT NULL)
    
    UNION ALL
    
    -- 递归:非叶子节点,累加直接子节点的calculated_cost
    SELECT 
        p.id, p.parent_id, p.label, p.cost,
        SUM(c.calculated_cost) AS calculated_cost
    FROM objective p
    JOIN recursive_calc c ON p.id = c.parent_id
    GROUP BY p.id, p.parent_id, p.label, p.cost
)
-- 按原层级顺序输出结果
SELECT 
    rc.id, rc.parent_id, rc.label, rc.cost, rc.calculated_cost
FROM recursive_calc rc
START WITH rc.parent_id IS NULL
CONNECT BY PRIOR rc.id = rc.parent_id
ORDER SIBLINGS BY rc.id;

方法2:原查询基础上结合子查询

如果不想用递归CTE,可以在原CONNECT BY查询中嵌套子查询,针对每个非叶子节点计算直接子节点的CALCULATED_COST总和:

SELECT 
    b.id, b.parent_id, b.label, b.cost,
    CASE
        -- 叶子节点直接取自身cost
        WHEN CONNECT_BY_ISLEAF = 1 THEN b.cost
        -- 非叶子节点计算直接子节点的calculated_cost之和
        ELSE (
            SELECT SUM(
                CASE WHEN CONNECT_BY_ISLEAF = 1 THEN c.cost ELSE 0 END
            )
            FROM objective c
            START WITH c.parent_id = b.id
            CONNECT BY PRIOR c.id = c.parent_id
        )
    END AS calculated_cost
FROM objective b
START WITH b.parent_id IS NULL
CONNECT BY PRIOR b.id = b.parent_id
ORDER SIBLINGS BY b.id;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:55:34