考虑以下示例结构:
一些数据,仅仅是为了下面的例子:
| ID | PARENT_ID | NAME | DEPTH |
|----|-----------|-------|-------|
| 1 | NULL | DEPT1 | 1 |
| 2 | 1 | DEPT2 | 2 |
| 3 | 1 | DEPT3 | 2 |
| 4 | 2 | DEPT4 | 3 |
| 5 | 3 | DEPT5 | 3 |
| 6 | NULL | DEPT6 | 1 |
| 7 | 6 | DEPT7 | 2 |
| ID | NAME | COST | DEPARTMENT_ID |
|------|--------|-------|---------------|
| 1 | PRJ1 | 100 | 1 |
| 2 | PRJ2 | 200 | 2 |
| 3 | PRJ3 | 300 | 3 |
| 4 | PRJ4 | 400 | 4 |
| 5 | PRJ5 | 500 | 5 |
| 6 | PRJ6 | 600 | 6 |
| 7 | PRJ7 | 700 | 7 |
现在,我需要以某种方式通过一个部门然后由直接子女来汇总项目的成本。
如果选择的过滤器为 DEPT1 ,则意图结果为:
| LINE | DEPARTMENT_ID | PARENT_ID | NAME | AGGREGATE_COST |
|------|----------------|-----------|--------|----------------|
| 1 | 1 | NULL | DEPT1 | 1500 |
| 2 | 2 | 1 | DEPT2 | 600 |
| 3 | 3 | 1 | DEPT3 | 800 |
其中:
编辑:
| ID | NAME | COST | DEPARTMENT_ID |
|------|--------|-------|---------------|
| 1 | PRJ1 | 1 | 1 |
| 2 | PRJ2 | 1 | 1 |
| 3 | PRJ3 | 1 | 2 |
| 4 | PRJ4 | 1 | 2 |
| 5 | PRJ5 | 1 | 4 |
在这种情况下,ivanzg提出的解决方案似乎不起作用。 对于最高级别的项目,我获得了双倍的结果
如果我得到DEPT1的聚合,它会返回类似于此的内容:
| LINE | DEPARTMENT_ID | PARENT_ID | NAME | AGGREGATE_COST |
|------|----------------|-----------|--------|----------------|
| 1 | 1 | NULL | DEPT1 | 8 |
| 2 | 2 | NULL | DEPT1 | 4 |
答案 0 :(得分:3)
您可以使用CONNECT_BY_ROOT层次结构运算符标记层次结构查询中的行(以便稍后创建组)。在层次结构查询中,通过将所有行根行创建为每个层次结构组合,稍后仅采用并聚合指定的组合。对于您的测试数据,这将返回您指定的内容。
SELECT ROOT_DEPT AS DEPARTMENT_ID
,ROOT_PARENT AS PARENT_ID
,ROOT_NAME AS NAME
,SUM(COST) AS AGGREGATE_COST
FROM (SELECT COST
,CONNECT_BY_ROOT DEPARTMENT_ID ROOT_DEPT
,CONNECT_BY_ROOT PARENT_ID ROOT_PARENT
,CONNECT_BY_ROOT NAME ROOT_NAME
FROM (SELECT B.DEPARTMENT_ID
,NVL(A.PARENT_ID,'0') PARENT_ID
,A.NAME
,SUM(B.COST) COST
FROM DEPARTMENT A
JOIN PROJECT B
ON A.ID = B.DEPARTMENT_ID
--> GROUP COST OF PROJECTS IN THE SAME DEPARTMENT IF THERE ARE ANY
GROUP BY B.DEPARTMENT_ID
,NVL(A.PARENT_ID,'0')
,A.NAME
)
--> MAKE ALL ROWS ROOT ROWS
CONNECT BY PRIOR DEPARTMENT_ID = PARENT_ID
)
WHERE ROOT_DEPT = 1 OR ROOT_PARENT = 1
GROUP BY ROOT_DEPT
,ROOT_PARENT
,ROOT_NAME