How can I sum up data in tree-like structure in SQL from children to parent?

寵の児 提交于 2019-12-12 18:13:27

问题


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 |

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/23607020/how-can-i-sum-up-data-in-tree-like-structure-in-sql-from-children-to-parent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!