Domanda

I have a query for selecting amounts per department in a tree-like structure. I want to display the sum amount of the children on their respective parent.

Is it possible to archive this in a query without using a cursor?

Below is a resultset of the data to sum up. A full sample can also be found on sqlfiddle.

Results:

| DEPARTMENT_ID | PARENT_DEP_ID |     DEPARTMENT |          AMOUNT |
|---------------|---------------|----------------|-----------------|
|             1 |             0 |              1 |               0 |
|             7 |             1 |             11 |               0 |
|            34 |             7 |            111 |               0 |
|           120 |            34 |           1111 |               0 |
|           402 |           120 |         111101 |               0 |
|           651 |           402 | 11110101/10000 | 227470.72339635 |
|           651 |           402 | 11110101/10000 |  52255.99610869 |
|           651 |           402 | 11110101/10000 |   4437.15281795 |
|           651 |           402 | 11110101/10000 |   4552.70289465 |
|           651 |           402 | 11110101/10000 |   8510.61790448 |
|           651 |           402 | 11110101/10000 |         8266.08 |
|           651 |           402 | 11110101/10000 |         9968.16 |
|           651 |           402 | 11110101/10000 |          242.58 |
|           403 |           120 |         111102 |               0 | <= this is where i
|           652 |           403 | 11110201/10005 |  120384.7842412 |    want to have my
|           652 |           403 | 11110201/10005 | 488733.59476206 |    sum from the 
|           652 |           403 | 11110201/10005 |    2318.6573888 |    child items
|           652 |           403 | 11110201/10005 |  23690.22829273 |
|           652 |           403 | 11110201/10005 | 38321.261680815 |
|           652 |           403 | 11110201/10005 |         6199.56 |
|           652 |           403 | 11110201/10005 |         7476.12 |
|           652 |           403 | 11110201/10005 |          161.92 |
È stato utile?

Soluzione

This will get the full report

SELECT t1.DEPARTMENT_ID
     , t1.PARENT_DEP_ID
     , t1.DEPARTMENT   
     , Sum(t2.Amount) Amount
FROM   TREE_DATA t1
       INNER JOIN TREE_DATA t2 
       ON t1.DEPARTMENT = SUBSTR(t2.DEPARTMENT, 1, LENGTH(t1.DEPARTMENT))
WHERE  t1.Amount = 0
GROUP BY t1.DEPARTMENT_ID, t1.PARENT_DEP_ID, t1.DEPARTMENT

UNION ALL

SELECT DEPARTMENT_ID
     , PARENT_DEP_ID
     , DEPARTMENT   
     , Amount
FROM   TREE_DATA
WHERE  Amount > 0
ORDER BY DEPARTMENT

The first query get the rolling sum by hacking the structure of the Department name for the oens without the amounts, the second one get the leafs.
The first query cannot show the leafs, as they will get grouped. I haven't found any column combination to get the same order, the leafs seems to be unordered.

SQLFiddle demo

I've tried to write a recursive CTE, but it's not possible to have aggregate function, such as SUM in it.

Altri suggerimenti

with rec(parent_dep_id, department_id, depth) as ( 
  select cast(null as int), 403, 0 from dual 
  union all 
  select rec.department_id, t.department_id, depth+1 
  from rec
     , tree_data t
  where depth<100
    and rec.department_id = t.parent_dep_id
) select sum(t.amount)
  from rec
  join tree_data t
      on rec.department_id = t.department_id

One can avoid the final join on tree_data by including amount in rec.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top