tags:

views:

58

answers:

2

The question is:

Two tables (t1, t2)

Table t1:

SELLER | NON_SELLER
    A     B
    A     C
    A     D
    B     A
    B     C
    B     D
    C     A
    C     B
    C     D
    D     A
    D     B
    D     C

Table t2:

SELLER | COUPON | BAL
A        9        100
B        9        200
C        9        300
D        9        400
A        9.5      100
B        9.5       20
A       10         80

Using SELECT Statement to get this result:

SELLER| COUPON | SUM(BAL)
A       9        900
B       9        800
C       9        700
D       9        600
A       9.5       20
B       9.5      100
C       9.5      120
D       9.5      120
A      10          0  # !!!
B      10         80
C      10         80
D      10         80

For seller A SUM(BAL) means sum( B.BAL,C.BAL,D.BAL), for B, SUM(BAL)=SUM(A.BAL,C.BAL,D.BAL)...

Please find a way with good performance and don't use temporary table.

My solution:
Running this query will get the result but without the row "A 10 0":

  select t1.seller, t2.coupon, sum(bal)
  from t1, t2
  where t1.non_seller = t2.seller
  group by t1.seller, t2.coupon
  order by t2.coupon

Please help ~~~~~~

+1  A: 

If I understand you correctly, you're looking for data on all sellers and all coupons. So let's start with a cross join that generates a list of coupons and sellers:

select  sellers.seller
,       coupons.coupon
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons

For each seller-coupon combination, you're looking for the sum they can buy from other sellers. This can be accomplished by a left join:

select  sellers.seller
,       coupons.coupon
,       case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons
left join
        Table2 t2
on      t2.seller <> sellers.seller
        and t2.coupon = coupons.coupon
group by
        sellers.seller
,       coupons.coupon

The only function of the case statement is to replace a null sum with a 0.

The output matches the one in your answer. Note that this solution doesn't use Table1: the list of other sellers is produced by the t2.seller <> sellers.seller condition in the left join.

Andomar
Great!!!!!!!!!! super thanks for @Andomar
Jammy Lee
I think for the first table of cross join we should use t1 , not t2, since the data of t2 may not include all sellers : ( select distinct seller from Table1 ) as sellers
Jammy Lee
A: 

I get another way to this:

  select t1.seller, t2.coupon, sum(bal)
  from t1, t2
  where t1.non_seller = t2.seller
  group by t1.seller, t2.coupon 
  union 
  (select seller,coupon,0 from t2 group by coupon having count(seller) == 1); 

And I don't know if it is better or worst than compare with @Andomar :

select  sellers.seller
,       coupons.coupon
,       case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from    (
        select  distinct seller
        from    Table2
        ) as sellers
cross join
        (
        select  distinct coupon
        from    Table2
        ) as coupons
left join
        Table2 t2
on      t2.seller <> sellers.seller
        and t2.coupon = coupons.coupon
group by
        sellers.seller
,       coupons.coupon
Jammy Lee