Home > database >  how can I calculate the sum according to the set of offer
how can I calculate the sum according to the set of offer

Time:03-22

I want to calculate the sum of the charges that will be grouped according to the User and the series of services. And I wonder, how I can joining the "charge" to user table?

I have a user table :

u_id offer_1 offer_2 offer_3
101 11
101 12 13
101 12
101 13
201 22 32 33

A transaction table:

u_id offer_id charge
101 11 150
101 12 150
101 13 200
201 22 300
201 32 100
201 33 45

My expected table is:

u_id offer_1 offer_2 offer_3 charge
101 11 150
101 12 13 350
101 12 150
101 13 200
201 22 32 33 445

I tried standard sum() function:

select u.u_id,u.offer_1,u.offer_2,u.offer_3,sum(t.charge)
from user u
left join transaction t on u.offer_1 = t.offer_id or u.offer_2 = t.offer_id  or u.offer_2 = t.offer_id 
group by u.u_id,u.offer_1,u.offer_2,u.offer_3

Can you help me?

CodePudding user response:

Test data (note I added a row with all null offers in the first table, to test correctness for that case too):

create table user_tbl (u_id, offer_1, offer_2, offer_3) as
    select 101,   11, null, null from dual union all
    select 101, null,   12,   13 from dual union all
    select 101, null,   12, null from dual union all
    select 101, null, null,   13 from dual union all
    select 201,   22,   32,   33 from dual union all
    select 201, null, null, null from dual
;

create table transactions (u_id, offer_id, change) as
    select 101, 11, 150 from dual union all
    select 101, 12, 150 from dual union all
    select 101, 13, 200 from dual union all
    select 201, 22, 300 from dual union all
    select 201, 32, 100 from dual union all
    select 201, 33,  45 from dual
;

Query and output:

with
  prep (rn, u_id, offer_1, offer_2, offer_3, o1, o2, o3) as (
    select rownum, u_id, offer_1, offer_2, offer_3, offer_1, offer_2, offer_3
    from   user_tbl
  )
select u_id, offer_1, offer_2, offer_3, nvl(sum(change), 0) as change
from   prep
unpivot include nulls (offer_id for col in (o1, o2, o3))
left outer join transactions using (u_id, offer_id)
group by u_id, offer_1, offer_2, offer_3, rn
;

      U_ID    OFFER_1    OFFER_2    OFFER_3     CHANGE
---------- ---------- ---------- ---------- ----------
       101         11                              150
       101                    12                   150
       101                    12         13        350
       101                               13        200
       201         22         32         33        445
       201                                           0

Unpivoting brings the data to a more familiar form, with one row per combination of u_id and "offer". The join is an outer join for two reasons: both because the unpivoting may generate null offers, and because a non-null offer may not have a match in the transactions table. (For that matter, a u_id may not have a match there either.) The rest is what you would expect - the outer join and the aggregation - and using nvl in the main select, assuming the change should be shown as zero (rather than null) when a row shows no actual offers.

  • Related