Oracle树形统计--子节点汇总到父节点

本文介绍了一种使用SQL实现树状结构数据汇总的方法。通过创建包含节点ID、父节点ID和值的表,并插入示例数据,展示了如何利用WITH语句和递归查询来计算每个节点及其子树的总值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始的树形数据状态:
      |--2(0)--4(100) 
0--1(0)--|

      |--3(0)--5(200)


汇总后的树形数据状态:      
           |--2(100)--4(100) 
0--1(300)--|
           |--3(200)--5(200)
           
create table t
(
   id number,
   parent_id number,
   value number
);
insert into t values(1,0,0);
insert into t values(2,1,0);
insert into t values(3,1,0);
insert into t values(4,2,100);
insert into t values(5,3,200);
commit;

SQL> select * from t order by id asc;
  ID  PARENT_ID      VALUE
---- ---------- ----------
   1          0          0
   2          1          0
   3          1          0
   4          2        100

   5          3        200


SQL> with ttt as (select t.*,SYS_CONNECT_BY_PATH(id,'/')||'/' path
    from t  start with t.parent_id=0 connect by prior t.id=   t.parent_id)
    SELECT id,
           parent_id,
           value,
          (SELECT SUM(value) FROM ttt WHERE path like t1.path || '%') s_value
      FROM ttt T1;
  ID  PARENT_ID      VALUE    S_VALUE
---- ---------- ---------- ----------
   1          0          0        300
   2          1          0        100
   4          2        100        100
   3          1          0        200
   5          3        200        200
### Oracle SQL 递归查询多个父节点树形结构 在Oracle数据库中,`CONNECT BY` 子句用于执行层次化查询。对于具有多个父节点树形结构,可以利用 `START WITH ... CONNECT BY PRIOR` 来实现递归查询。 当涉及到多父节点的情况时,表设计通常会包含一个自连接关系来表示子之间的关联。为了展示这种类型的查询方法,假设有一个名为 `tree_structure` 的表格,其中每一行代表树中的一个节点,并且有字段 `id`, `parent_ids` 表示当前节点及其可能存在的多个ID列表: ```sql WITH RECURSIVE TreeCTE AS ( SELECT id, parent_ids, CAST(id AS VARCHAR(255)) AS path FROM tree_structure t1 WHERE NOT EXISTS (SELECT * FROM tree_structure t2 WHERE FIND_IN_SET(t1.id, t2.parent_ids)) UNION ALL SELECT ts.id, ts.parent_ids, CONCAT(tc.path, '->', ts.id) FROM TreeCTE tc INNER JOIN tree_structure ts ON FIND_IN_SET(ts.id, tc.parent_ids) > 0 ) SELECT * FROM TreeCTE; ``` 此代码片段创建了一个公共表达式(Common Table Expression),它首先选择了那些没有任何其他记录作为其母的所有根节点;接着通过递归部分加入它们的孩子们直到遍历整个树状图谱[^1]。 需要注意的是,在上述例子中使用了 MySQL 函数 `FIND_IN_SET()` 和字符串拼接函数 `CONCAT()`. 对于 Oracle 数据库而言,应该替换为相应的内置功能如 `INSTR()` 或者正则表达式的匹配方式以及 `||` 进行字符串连接操作: ```sql WITH RecursiveTree AS ( SELECT id, parent_ids, TO_CHAR(id) AS PATH FROM tree_structure t1 WHERE NOT EXISTS (SELECT NULL FROM tree_structure t2 WHERE INSTR(',' || t2.parent_ids || ',', ',' || t1.id || ',') > 0) UNION ALL SELECT ts.id, ts.parent_ids, rt.PATH || '->' || TO_CHAR(ts.id) FROM RecursiveTree rt INNER JOIN tree_structure ts ON INSTR(',' || rt.parent_ids || ',', ',' || ts.id || ',') > 0 ) SELECT * FROM RecursiveTree; ``` 在这个调整后的版本里,`TO_CHAR()` 被用来转换数值型 ID 成字符形式以便更容易地构建路径字符串,而 `INSTR()` 则是用来检测某个特定值是否存在于逗号分隔的字符串集合之中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值