简体   繁体   English

具有累积计数的Oracle分层SQL

[英]Oracle hierarchical sql with rollup count

How would I write SQL in Oracle to return tree view with rolloup count: 我将如何在Oracle中编写SQL以返回具有汇总计数的树视图:

SQL would return this: SQL将返回以下内容:

KLAS - COUNT

----------------------------------------------

ROOT - 10

   KLAS1 - 5

       KLAS2 - 2

       KLAS3 - 3

  KLAS4 - 5

       KLAS5 - 5

  KLAS6 - 0

       KLAS7 - 0

I have two tables, one is where is structure hold, second is where I have data. 我有两个表,一个是结构保留的位置,第二个是数据存储的位置。 Both tables are joined by klas coumn 两个表都由klas coumn连接

Code for reproducing tables: 复制表的代码:

create table table1 (id number, parent_id number, klas varchar2(10));  
insert into table1 (id, parent_id, klas) values (1, null, 'ROOT');  
insert into table1 (id, parent_id, klas) values (2, 1, 'KLAS1');  
insert into table1 (id, parent_id, klas) values (3, 2, 'KLAS2');  
insert into table1 (id, parent_id, klas) values (4, 2, 'KLAS3');  
insert into table1 (id, parent_id, klas) values (5, 1, 'KLAS4');  
insert into table1 (id, parent_id, klas) values (6, 5, 'KLAS5');  
insert into table1 (id, parent_id, klas) values (7, 1, 'KLAS6');  
insert into table1 (id, parent_id, klas) values (8, 7, 'KLAS7');  



create table table2 (klas varchar2(10), cnt number);  
insert into table2(klas, cnt) values ('KLAS2', 2);  
insert into table2(klas, cnt) values ('KLAS3', 3);  
insert into table2(klas, cnt) values ('KLAS5', 5);  

commit;  

Regards, Igor 问候,伊戈尔

with c1 (parent_id, id, klas, p, o) as
(
  select 
     parent_id, id, klas, '' as p, lpad(id, 10, '0') as o
     from table1
     where parent_id is null
  union all
  select 
     table1.parent_id, table1.id, table1.klas, 
     c1.p || '.....',
     c1.o || '.' || lpad(table1.id, 10, '0') as o
     from table1
     inner join c1 on table1.parent_id = c1.id
),
c2 (id, klas, p, o, cnt) as
(
  select c1.id, c1.klas, c1.p, c1.o, nvl(table2.cnt, 0)
  from c1
  left outer join table2 on c1.klas = table2.klas
)
select c3.p || c3.klas, (select sum(cnt) from c2 where c2.o like c3.o || '%') from c2 c3
order by c3.o

SQLFiddle - http://sqlfiddle.com/#!4/be779/97 SQLFiddle- http: //sqlfiddle.com/#!4/be779/97

Explanation 说明

The first CTE is for positioning (ie the .....) and ordering (this is done by constructing column o that ensures that children come under the parent (so if the parent o is xxxx, the child will be xxxx || ) 第一个CTE用于定位(即......)和排序(这是通过构造列o来完成的,以确保子代位于父代之下(因此,如果父代o是xxxx,则子代将是xxxx ||)

The 2nd CTE just gets the cnts - I think you can do it in the first CTE itself, but that would have been difficult to understand. 第二个CTE刚获得cnts-我想您可以在第一个CTE本身中做到这一点,但这很难理解。

The subquery in the final query just gets the sum of a node and it's children. 最终查询中的子查询仅获得一个节点及其子节点之和。

Limits 范围

  1. Note that you can go up to 10 digit IDs on this one, if you want to go over that you have to change the 10 on the lpad. 请注意,您可以在此ID上最多输入10个数字ID,如果要翻阅,则必须在lpad上更改10。
  2. The limit on depth depends on the varchar(max) - you add 11 characters (10 + one .) for each level. 深度限制取决于varchar(max)-您为每个级别添加11个字符(10 +一个。)。 You can increase your depth limit if you are willing to limit your id length (a 5 digit long id will only add 6 characters for each level). 如果您愿意限制自己的ID长度,则可以增加深度限制(一个5位数长的ID只会为每个级别添加6个字符)。
  3. For o, you actually don't need the ., but it help understand what is going on. 对于o,您实际上不需要。,但是它有助于了解发生了什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM