Reputation: 741
I have two tables .
Input:
I have joined with the calendar table and bring the data till current.
I need a output .
I tried a query with UNION and Aggregation but I need to query two times and aggregate the same table . Since the table is very big .Is there a option to do different way
SELECT ID ,PERIOD,SUM(AMOUNTYTD) AMOUNTYTD,SUM(AMOUNT) AMOUNT
FROM (
SELECT ID ,b.PERIOD,SUM(AMOUNT) AMOUNTYTD,0 AMOUNT
FROM transaction a RIGHT OUTER JOIN CALENDAR b
ON b.PERIOD<=a.PERIOD
UNION ALL
SELECT ID ,PERIOD,0,SUM(AMOUNT)
FROM transaction
GROUP BY ID,PERIOD
)
GROUP BY ID,PERIOD
Upvotes: 1
Views: 87
Reputation: 35930
You have the query - I have joined with the calendar table and bring the data till current.
let us assume it as your_query
You can use analytical function on it as follows:
Select t.*,
Case when lead(amountytd) over (partition by id order by period) = amountytd
then null
else amountytd
end as amount
From (your_query) t
Upvotes: 0
Reputation:
Showing the periodic amount side by side with the cumulative amount is easy - actually you only need to be able to create the correct table with the periodic amounts, the cumulative amounts are a simple application of analytic sum.
The key to joining the calendar table to the "input" data is to use a partitioned outer join - notice the partition by (id)
clause in the join of the two tables. This causes the "inputs" data to be partitioned into separate sub-tables, one for each distinct id
; the outer join to the calendar table is done separately for each such sub-table, and then the results are combined with a logical "union all".
with
input (id, period, amount) as (
select 1, 202010, 100 from dual union all
select 1, 202011, 50 from dual union all
select 2, 202011, 400 from dual
)
, calendar (period) as (
select 202010 from dual union all
select 202011 from dual union all
select 202012 from dual union all
select 202101 from dual
)
select id, period, amountytd, amount
from (
select i.id, period, i.amount,
sum(i.amount) over (partition by i.id order by period)
as amountytd
from calendar c left outer join input i partition by (id)
using (period)
)
where amountytd is not null
order by id, period
;
ID PERIOD AMOUNTYTD AMOUNT
--- ---------- ---------- ----------
1 202010 100 100
1 202011 150 50
1 202012 150
1 202101 150
2 202011 400 400
2 202012 400
2 202101 400
Upvotes: 3