Reputation: 309
I have a data set that lists an employee id, code, hours and wages. Any 1 employee can have 1 of either OT1 or OT2, or they could have 1 row of both. The short of it is that I need to sum all of the wages, but if they have both codes to just take the amount for OT1. Then I want to divide total wages by the hours in the condition I stated. Example Data:
+ -------+------+-------+--------+ | ID | CODE | HOURS | AMOUNT | + -------+------+-------+--------+ | 123456 | OT1 | 10 | 80 | | 789000 | OT1 | 8 | 120 | | 789000 | OT2 | 8 | 60 | | 654111 | OT2 | 4 | 40 | + -------+------+-------+--------+
I'm attempting to add a new column to divide the amount by the hours and will remove the code column so we can sum each employee to have a single record. The catch is, if the employee has both OT1 and OT2, I don't want to sum those , I just want the hours from OT1. That logic manually applied to my previous example
+ -------+-------+--------+---------+ | ID | HOURS | AMOUNT | AVERAGE | + -------+-------+--------+---------+ | 123456 | 10 | 80 | 8 | | 789000 | 8 | 180 | 22.5 | | 654111 | 4 | 40 | 10 | + -------+-------+--------+---------+
Upvotes: 0
Views: 59
Reputation: 1269763
You can do this using conditional aggregation:
select id,
coalesce(sum(case when code = 'OT1' then hours end),
sum(hours)
) as hours,
sum(amount) as amount,
(sum(amount) /
coalesce(sum(case when code = 'OT1' then hours end),
sum(hours)
)
) as average
from t
group by id
order by id;
This method explicitly combines values from multiple rows, so it should work as expected if there are duplicates.
Upvotes: 1
Reputation: 94914
You get the hours for the first code with Oracle's KEEP FIRST
:
select
id,
min(hours) keep (dense_rank first order by code) as hours,
sum(amount) as amount,
round(sum(amount) / min(hours) keep (dense_rank first order by code), 2) as average
from mytable
group by id
order by id;
Upvotes: 1