如何将叶子节点的数据合计到父节点 by Oracle 10g

汇总父节点数据
本文介绍了一种在Oracle数据库中将叶子节点的数值汇总到其对应父节点的方法。通过使用CONNECT BY和START WITH子句,可以有效地计算出每个父节点下所有叶子节点数值的总和。

原文地址在这里:【难题】如何将叶子节点的数据合计到父节点,原文已经不能回复了,在这里写下解法。

题目简单描述如下:

有数据表结构如下,只有叶子节点有数据:


1
2
3
4
5
6
id  parentId    name        amount
1               成本    
2    1          工资  
3    2          基本工资    1000 
4    2          奖金        200
5    1          保险        400

现在想统计处父节点合计数 ,如下:


1
2
3
4
5
6
id      name       amount
1       成本       1600    //2 + 5
2       工资       1200    //3 + 4
3       基本工资   1000 
4       奖金       200
5       保险       400

作者要求是Oracle数据库。

由于功力不够求助了ITPUB上的大牛,也得到了精妙的回复,在这里记录一下:

为节省篇幅,使用CTE语法构建临时表,不再建表了:


1
2
3
4
5
6
7
8
with tmp as (
   select 1 as id , null as parentid , '成本' as name , null as amount from dual union all
   select 2,1 , '工资' , null from dual union all
   select 3,2 , '基本工资' , 1000 from dual union all
   select 4,2 , '奖金' , 200 from dual union all
   select 5,1 , '保险' , 400 from dual
)
select * from tmp

1
2
3
4
5
6
7
ID                     PARENTID               NAME     AMOUNT                
---------------------- ---------------------- -------- ----------------------
1                                             成本                          
2                      1                      工资                          
3                      2                      基本工资  1000                 
4                      2                      奖金     200                   
5                      1                      保险     400

首先是来自2楼newkid的解法:


1
2
3
4
5
6
7
8
SELECT root_id, SUM (amount)
   FROM (
     select CONNECT_BY_ROOT(id) root_id,amount
       from tmp
      WHERE CONNECT_BY_ISLEAF=1
    CONNECT BY PRIOR id = parentid
)
GROUP BY root_id;

然后是3楼dingjun123的解法:


1
2
3
4
5
6
7
SELECT id,parentid, name ,
   ( SELECT SUM (amount)
       FROM tmp a
      START WITH a.id=b.id
    CONNECT BY PRIOR a.id=a.parentid ) sum_sal
   FROM tmp b
  ORDER BY 1;

基本思路都是利用 connect by 子句自根节点/分支节点往叶子结点搜索,找出不同的根节点/分支节点到叶子节点的路径再求和,修改一下newkid的子查询并查看一下结果集就比较明了:


1
2
3
4
   select CONNECT_BY_ROOT(id) start_id,id leaf_id,amount
    from tmp
   WHERE CONNECT_BY_ISLEAF=1
CONNECT BY PRIOR id = parentid

1
2
3
4
5
6
7
8
9
10
   START_ID    LEAF_ID     AMOUNT
---------- ---------- ----------
          1          3       1000
          1          4        200
          1          5        400
          2          3       1000
          2          4        200
          3          3       1000
          4          4        200
          5          5        400

start_id 就是开始查找(不是start with)的节点id,leaf_id就是叶子节点的id,用图来帮助分析:

image

可以看到id=1的节点,也就是根节点的值等于三个叶子节点的值的总和,叶子节点的值是明确的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值