Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL SUM function in multiple joins

Tags:

sql

join

mysql

Hi so this is my case I have those tables

Customer {id,name}
Charges {id,amount,customer_id}
Taxes {id,amount,charge_id}

so I want to SUM amount of charges and taxes then group by customer id here is my query

SELECT SUM(ch.amount),SUM(t.amount)
FROM Customer c
LEFT JOIN Charges ch ON ch.customer_id = c.id
LEFT JOIN Taxes t ON t.charge_id = ch.id
GROUP BY c.id;

so in case I have 1 charge for customer than I have 2 taxes for that charge when I use SUM function it's counting amount of charge twice for example in case to show me 10$ it' showing me 20$

I know how can I fix that through subqueries, but I want to know is there any option to get correct value without subqueries like query I use above what can I modify there to fix that.

Thanks !

UPDATED ANSWER WITHOUT SUBQUERIES

SELECT
  SUM(CASE WHEN @ch_id != ch.id
    THEN ch.amount END) AS ch_amount,
  SUM(t.amount)         AS t_sum,
  c.*,
  @ch_id := ch.id
FROM
  Customer c
  LEFT JOIN charges ch ON c.id = ch.reservation_id
  LEFT JOIN taxes t ON ch.id = t.charge_id
GROUP BY rs.id;
like image 683
G.L Avatar asked Mar 10 '23 19:03

G.L


2 Answers

You want to know if you can do this without subqueries. No, you can't.

If a row in Charges has more than one corresponding row in Taxes, you can't simply join the tables without duplicating Charges rows. Then, as you have discovered, when you sum them up, you'll get multiple copies.

You need a way to get a virtual table (a subquery) with one row for each Charge.

                    SELECT ch.customer_id,
                           ch.amount amount,
                           tx.tax tax
                      FROM Charges
                      LEFT JOIN (  
                                  SELECT SUM(amount) tax,
                                         charge_id 
                                    FROM Taxes
                                   GROUP BY charge_id
                          ) tx ON ch.id = tx.charge_id

You can then join that subquery to your Customer table to summarize sales by customer.

like image 166
O. Jones Avatar answered Mar 21 '23 08:03

O. Jones


This is a pain because of the multiple hierarchies. I would suggest:

SELECT c.id, ch.charge_amount, ch.taxes_amount
FROM Customer c LEFT JOIN
     (SELECT ch.customer_id, SUM(ch.amount) as charge_amount,
             SUM(t.taxes_amount) as taxes_amount
      FROM Charges ch LEFT JOIN
           (SELECT t.charge_id, SUM(t.amounts) as taxes_amount
            FROM taxes t
            GROUP BY t.charge_id
           ) t
           ON t.charge_id = ch.id
      GROUP BY ch.customer_id
     ) ch
     ON ch.customer_id = c.id;

You are not going to be able to fix this without subqueries of one form or another, if there are multiple charges for a customer or multiple taxes on a charge.

like image 27
Gordon Linoff Avatar answered Mar 21 '23 08:03

Gordon Linoff