Hi there,
nice real life use case of a complex aggregation function that includes multiple aggregation levels (in SAP BW terms similar to constant selection) and non-numeric aggregation logic.
Here's my go at it (with some other sample data):
create column table item_and_whole (complaint_id integer, item_id integer, status varchar(30)); truncate table item_and_whole; insert into item_and_whole values (1, 1, 'accepted'); insert into item_and_whole values (1, 2, 'accepted'); insert into item_and_whole values (2, 1, 'accepted'); insert into item_and_whole values (2, 2, 'rejected'); insert into item_and_whole values (3, 1, 'rejected'); insert into item_and_whole values (3, 2, 'rejected'); insert into item_and_whole values (3, 3, 'rejected');
So far, so good - all three cases are in there.
Now, my approach looks at the number of different status values per complaint_id and also gets the "maximum" status.
This is merely to be able to distinguish between the cases where all items share the same status, but could be used otherwise as well.
In the final selection list I decode the two aggregate information via a case statement:
select iaw.complaint_id, iaw.item_id, iaw.status, st.max_stat, st.dist_stat, case when (st.dist_stat = 1) then 'All items ' || st.max_stat when (st.dist_stat > 1) then ' partially rejected' else ' mixed status ' end as complaint_status from item_and_whole iaw inner join (select st.complaint_id , max(st.status) as max_stat , count(distinct st.status) as dist_stat from item_and_whole st group by st.complaint_id) st on iaw.complaint_id = st.complaint_id order by complaint_id, item_id;
| COMPLAINT_ID | ITEM_ID | STATUS | MAX_STAT | DIST_STAT | COMPLAINT_STATUS |
| 1 | 1 | accepted | accepted | 1 | All items accepted |
| 1 | 2 | accepted | accepted | 1 | All items accepted |
| 2 | 1 | accepted | rejected | 2 | partially rejected |
| 2 | 2 | rejected | rejected | 2 | partially rejected |
| 3 | 1 | rejected | rejected | 1 | All items rejected |
| 3 | 2 | rejected | rejected | 1 | All items rejected |
| 3 | 3 | rejected | rejected | 1 | All items rejected |
Depending on your use case, you might consider putting this into a function.