Reputation: 415
I'm trying to get the aggregation amount over the past rolling 3 days for each separated group. However, I don't get what I expected. Can anyone show me how to produce the expected output, maybe using pivot?
however, my result separated the groups, giving me result when the group is red, and null if it's yellow. however, I want the result such that even though the group is yellow, the data is still not null, but just duplicate the previous number. Maybe try it with pivot?
select *,
case when group = 'Red' then count(NVL(amount,0)) OVER (PARTITION BY ACCOUNT, group ORDER BY day_number range 2 PRECEDING),
case when group = 'Yellow' then count(NVL(amount,0)) OVER (PARTITION BY ACCOUNT, group ORDER BY day_number range 2 PRECEDING)
from table
expected output
Account Group Sum day_number Red Yellow
abc Red 20 1 20 0
abc Red 30 3 50 0
abc Yellow 40 4 50 40
def Red 20 5 20 40
def Yellow 50 8 0 50
def Yellow 20 9 0 70
wrong output
Account Group Sum day_number Red Yellow
abc Red 20 1 20
abc Red 30 3 50
abc Yellow 40 4 40
def Red 20 5 20
def Yellow 50 8 50
def Yellow 20 9 70
Upvotes: 0
Views: 48
Reputation: 1270713
I think you mostly want sum()
instead of count()
:
select t.*,
(case when group = 'Red'
then sum(amount) over (partition by account, group order by day_number range between 2 preceding and current row)
end) as red,
(case when group = 'Yellow'
then sum(amount) over (partition by account, group order by day_number range between 2 preceding and current row)
end) as red
from table t
Upvotes: 1
Reputation: 14858
If you want to make red
and yellow
columns independent from account and group then simply remove partition by
part.
select t.*,
nvl(sum(case grp when 'Red' then amount end)
over (order by day_number range 2 preceding), 0) red,
nvl(sum(case grp when 'Yellow' then amount end)
over (order by day_number range 2 preceding), 0) yellow
from t
which gives us result:
ACCOUNT GRP AMOUNT DAY_NUMBER RED YELLOW
------- ------ ---------- ---------- ---------- ----------
abc Red 20 1 20 0
abc Red 30 3 50 0
abc Yellow 40 4 30 40
def Red 20 5 50 40
def Yellow 50 8 0 50
def Yellow 20 9 0 70
Note that there is difference in third row in column RED
(you typed 50, query shows 30), but for day 4
we have only one red value from two previous days, which is 30
.
If you simply need to repeat values for nulls then use lag
instead, but this makes no sense for me.
You can do it with pivot
, but you had to prepare data properly in subquery, then make pivot. In this case case when
syntax is more readable.
Upvotes: 1