简体   繁体   中英

Summing unrelated columns in two tables, then joining based on an ID

I have two tables set up basically like this (extremely lite version):

Table 1 :

ID       Amt 1     Amt 2
-------------------------    
112     $20        $30
112     $50        $60
125     $75        $05

Table 2 :

ID       Amt 3     Amt 4
-------------------------
112       $25       $30
125       $40       $60
125      $110      $120

All the amount columns needed to be summed separately, the output to be similar to this:

Query results:

ID       Amt 1     Amt 2     Amt 3     Amt 4
--------------------------------------------
112     $70        $90       $25       $30
125     $75        $05       $150      $180

The joins I've tried result in the records duplicating (and summing) by a factor of the times the ID repeats in the second table. I have no primary key to connect these tables.

Any help would be greatly appreciated.

Thanks!

To solve this problem correctly, you need to do the aggregations separately. This will work even when both tables have multiple rows for the same id:

select id, sum(amt1), sum(amt2), sum(amt3), sum(amt4)
from ((select id, sum(amt1) as amt1, sum(amt2) as amt2, NULL as amt3, NULL as amt4
       from tbl1
       group by id
      ) union all
      (select id, NULL, NULL, sum(amt3), sum(amt4)
       from tbl2
       group by id
      )
     ) t
group by id

The above query gives the idea with a group by . Some people prefer a full outer join for this purpose:

select coalesce(t1.id, t2.id) as id, amt1, amt2, amt3, amt4
from (select id, sum(amt1) as amt1, sum(amt2) as amt2
       from tbl1
       group by id
      ) t1 full outer join
      (select id, sum(amt3) as amt3, sum(amt4) as amt4
       from tbl2
       group by id
      ) t2
      on t1.id = t2.id

The key is that the aggregations have to be done before any joins, so you don't have a problem of multiple rows.

On SQL Server 2005 or newer, you could use two CTE's (Common Table Expression) to do the summing/grouping per table, and then join the two - something like this:

;WITH CTE1 AS
(
    SELECT 
        ID, Amount1 = SUM(Amt1), Amount2 = SUM(Amt2)
    FROM
        dbo.SumTbl1
    GROUP BY
        ID  
),
CTE2 AS
(
    SELECT 
        ID, Amount3 = SUM(Amt3), Amount4 = SUM(Amt4)
    FROM
        dbo.SumTbl2
    GROUP BY
        ID  
)
SELECT CTE1.ID, Amount1, Amount2, Amount3, Amount4
FROM CTE1
INNER JOIN CTE2 ON CTE1.ID = CTE2.ID

This gives me your desired output

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM