Oracle树形汇总--connect_by_root
有个需求:统计上级部门的销售额,制造数据如下:
drop table dept; create table dept ( DEPTNO number, DEPTNAME varchar2(50), PARENT_DEPTNO number ); insert into dept values(1,'市场部',-1); insert into dept values(2,'市场一部',1); insert into dept values(3,'市场二部',1); insert into dept values(4,'销售一组',2); insert into dept values(5,'销售二组',2); insert into dept values(6,'销售三组',3); insert into dept values(7,'销售四组',3); insert into dept values(8,'电力1',4); insert into dept values(9,'电力2',5); insert into dept values(10,'电力3',4); insert into dept values(11,'电力4',5); insert into dept values(12,'石油1',6); insert into dept values(13,'石油2',7); insert into dept values(14,'石油3',6); insert into dept values(15,'石油4',7); commit; drop table sales; create table sales ( id number, sale_num number, deptno number ); insert into sales values(1,50000,8); insert into sales values(2,10000,9); insert into sales values(3,60000,10); insert into sales values(4,10000,11); insert into sales values(5,20000,12); insert into sales values(6,40000,13); insert into sales values(7,90000,14); insert into sales values(8,110000,15); commit; select dd.deptno, dd.deptname, nvl(s.sale_num, 0) sale_num, dd.parent_deptno from (select d.deptno, cast(lpad(' ', level * 2 - 1) || d.deptname as varchar2(50)) deptname, rownum rn, d.parent_deptno from dept d start with d.PARENT_DEPTNO = -1 connect by prior d.DEPTNO = d.PARENT_DEPTNO) dd, sales s where dd.deptno = s.deptno(+) order by dd.rn; DEPTNO DEPTNAME SALE_NUM PARENT_DEPTNO -------- -------------------------------------------------- ---------- -------------
1 市场部 0 -1
2 市场一部 0 1
4 销售一组 0 2
8 电力1 50000 4
10 电力3 60000 4
5 销售二组 0 2
9 电力2 10000 5
11 电力4 10000 5
3 市场二部 0 1
6 销售三组 0 3
12 石油1 20000 6
14 石油3 90000 6
7 销售四组 0 3
13 石油2 40000 7
15 石油4 110000 7
统计所有父部门的营业额。
思路1:先将所有的父部门查出来,然后弄一个子查询做递归查询出其子节点,然后求和,这种思路很简单,效率也低,不推荐。
思路2:先用层次查询查出树形结构,要想统计一个节点下的汇总,需要用到connect_by_root,同一个节点下的connect_by_root是一样的,然后再group by。
--实现如下
with temp as (select dd.deptno,nvl(s.sale_num, 0) sale_num,root_id,rn from (select d.deptno, connect_by_root(d.deptno) root_id, rownum rn from dept d start with d.PARENT_DEPTNO in(select PARENT_DEPTNO from dept) connect by prior d.DEPTNO = d.PARENT_DEPTNO) dd, sales s where dd.deptno = s.deptno order by dd.rn), temp1 as(select root_id,sum(sale_num) s_sum from temp group by root_id), temp3 as( --加上temp3纯粹是为了阅读方便 select d.deptno, cast(lpad(' ', level * 2 - 1) || d.deptname as varchar2(50)) deptname, rownum rn from dept d start with d.PARENT_DEPTNO = -1 connect by prior d.DEPTNO = d.PARENT_DEPTNO ) select t3.deptno,t3.deptname,t1.s_sum from temp1 t1,temp3 t3 where t1.root_id = t3.deptno order by rn; DEPTNO DEPTNAME S_SUM
---------- -------------------------------------------------- ----------
1 市场部 390000
2 市场一部 130000
4 销售一组 110000
8 电力1 50000
10 电力3 60000
5 销售二组 20000
9 电力2 10000
11 电力4 10000
3 市场二部 260000
6 销售三组 110000
12 石油1 20000
14 石油3 90000
7 销售四组 150000
13 石油2 40000
15 石油4 110000
已选择15行。
本站文章为和通数据库网友分享或者投稿,欢迎任何形式的转载,但请务必注明出处.
同时文章内容如有侵犯了您的权益,请联系QQ:970679559,我们会在尽快处理。