Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mysql join and sum is doubling result

I have a table of revenue as

title_id     revenue    cost
   1            10        5
   2            10        5
   3            10        5
   4            10        5
   1            20        6                    
   2            20        6
   3            20        6
   4            20        6

when i execute this query

SELECT SUM(revenue),SUM(cost)
FROM revenue
GROUP BY revenue.title_id

it produces result

title_id     revenue    cost
   1            30        11
   2            30        11
   3            30        11
   4            30        11

which is ok, now i want to combine sum result with another table which has structure like this

title_id     interest    
   1            10        
   2            10        
   3            10        
   4            10        
   1            20                            
   2            20        
   3            20        
   4            20        

when i execute join with aggregate function like this

SELECT SUM(revenue),SUM(cost),SUM(interest)
FROM revenue
LEFT JOIN fund ON revenue.title_id = fund.title_id
GROUP BY revenue.title_id,fund.title_id      

it double the result

title_id     revenue    cost    interest
   1            60        22       60
   2            60        22       60
   3            60        22       60
   4            60        22       60

I can't understand why is it double it,please help

like image 599
Arslan Ali Avatar asked Jul 06 '12 14:07

Arslan Ali


3 Answers

Its doubling because you have title repeated in fund and revenue tables. This multiplies the number of records where it matches. This is pretty easy to see if you remove the aggregate functions and look at the raw data. See here

The way to get around this is to create inline views of your aggregates and join on the those results.

SELECT R.title_id, 
       R.revenue, 
       R.cost, 
       F.interest 
FROM   (SELECT title_id, 
               Sum(revenue) revenue, 
               Sum(cost)    cost 
        FROM   revenue 
        GROUP  BY revenue.title_id) r 
       LEFT JOIN (SELECT title_id, 
                         Sum(interest) interest 
                  FROM   fund 
                  GROUP  BY title_id) f 
              ON r.title_id = F.title_id 

output

| TITLE_ID | REVENUE | COST | INTEREST |
----------------------------------------
|        1 |      30 |   11 |       30 |
|        2 |      30 |   11 |       30 |
|        3 |      30 |   11 |       30 |
|        4 |      30 |   11 |       30 |

demo

like image 135
Conrad Frix Avatar answered Nov 07 '22 03:11

Conrad Frix


The reason for this is that you have joined the table the first derived table from the second table without grouping it. To solve the problem, group the second table (fund) and join it with the first derived table using LEFT JOIN.

SELECT  b.title_id,
        b.TotalRevenue,
        b.TotalCost,
        d.TotalInterest
FROM 
(
    SELECT   a.title_id, 
             SUM(a.revenue) TotalRevenue, 
             SUM(a.cost) TotalCost
    FROM     revenue a
    GROUP BY a.title_id
) b LEFT JOIN
(
    SELECT   c.title_id, 
             SUM(a.interest) TotalInterest
    FROM     fund c
    GROUP BY c.title_id
) d ON b.title_id = d.title_id
like image 3
Walter Avatar answered Nov 07 '22 03:11

Walter


There are two rows for each title_id in revenue table.

like image 1
srini.venigalla Avatar answered Nov 07 '22 03:11

srini.venigalla