Reputation: 497
I have a requirement where I need to sum up all the child of a node.
And the Output should be
D023343 120
D022959 120
D023375 50
D035738 10
D024481 0
I tried using diff queries but it is not getting the required . Kindly help
SELECT * FROM (SELECT a.child achild,b.child bchild,a.parent aparent,b.parent bparent,a.sales,b.sales
FROM TEST a,TEST b
WHERE a.CHILD='D023375')
where aparent!=bchild
and achild=bparent
Kindly help.
Thanks
Upvotes: 0
Views: 1450
Reputation: 351369
You can use a recursive common table expression as defined in the SQL-99 standard. Oracle calls this recursive subquery factoring. You'll also need to do something to get the last record with 0 sales in the result, since there is no record that explicitly defines that sales amount.
Here is how such a query would look:
with base(parent, child, sales) as (
select parent, child, sales
from tbl
union all -- add the 0 sales records
select child, null, 0
from tbl
),
rec(parent,child,sales) as ( -- recursive query
select parent, child, sales
from base
union all
select rec.parent, base.child, base.sales
from base
inner join rec on base.parent = rec.child
)
select parent, sum(sales)
from rec
group by parent
order by 1
NB: this syntax is supported as of Oracle 11g Release 2.
Upvotes: 1
Reputation: 168741
Use a hierarchical query to traverse the hierarchy and CONNECT_BY_ROOT()
to reference the top of the hierarchy - you can then use that to group the query to get the totals of the descendants.
Oracle 11g R2 Schema Setup:
CREATE TABLE your_table( parent, child, sales ) AS
SELECT 'D023343', 'D022959', 0 FROM DUAL UNION ALL
SELECT 'D022959', 'D023375', 60 FROM DUAL UNION ALL
SELECT 'D023375', 'D035738', 50 FROM DUAL UNION ALL
SELECT 'D035738', 'D024481', 10 FROM DUAL;
Query 1:
SELECT root,
SUM( sales ) AS total_sales
FROM (
SELECT CONNECT_BY_ROOT( parent ) AS root,
sales
FROM your_table
CONNECT BY PRIOR child = parent
)
GROUP BY root
| ROOT | TOTAL_SALES |
|---------|-------------|
| D023375 | 60 |
| D035738 | 10 |
| D023343 | 120 |
| D022959 | 120 |
If you want the leaf children that have no sales then you will need to do something like appending
UNION ALL
SELECT child, 0 FROM your_table
to the inner query.
Upvotes: 2