ABHIJIT
ABHIJIT

Reputation: 689

Sql sum() columns from different tables

Category Table

mysql> SELECT * FROM cats;
+------+------+-----------+
| c_id | p_id | c_name    |
+------+------+-----------+
|    1 |    1 | cats 1    |
|    2 |    1 | cats 2    |
|    3 |    1 | cats 3    |
+------+------+-----------+

Meta Table

mysql> SELECT * FROM meta;
+------+------+------+---------+-------------+-------+
| m_id | p_id | c_id | name    | description | costs |
+------+------+------+---------+-------------+-------+
|    1 |    1 |    1 | Abhijit | description | 100   |
|    2 |    1 |    1 | Abhijit | description | 200   |
|    3 |    1 |    2 | Abhiji2 | description | 500   |
+------+------+------+---------+-------------+-------+

Transaction Table

mysql> SELECT * FROM transactions;
+------+------+------+---------------------+--------+
| t_id | p_id | m_id | date                | amount |
+------+------+------+---------------------+--------+
|    1 |    1 |    1 | 2016-02-16 11:17:06 | 50     |
|    2 |    1 |    1 | 2016-02-16 11:17:06 | 50     |
|    3 |    1 |    2 | 2016-02-16 11:17:06 | 50     |
|    4 |    1 |    2 | 2016-02-16 11:17:06 | 150    |
+------+------+------+---------------------+--------+

I want to sum() for each category costs (from meta table) and amount( from transaction table).

I use:

mysql> SELECT c.*, SUM(t.amount), SUM(m.costs)
    FROM cats c
        LEFT JOIN meta m ON m.c_id=c.c_id
        LEFT JOIN transactions t ON t.m_id=m.m_id
    GROUP BY c.c_id;

+------+------+-----------+--------+---------------+--------------+
| c_id | p_id | c_name    | add_by | SUM(t.amount) | SUM(m.costs) |
+------+------+-----------+--------+---------------+--------------+
|    1 |    1 | Abhijit   |      1 |           100 |          400 |
|    2 |    1 | Abhiji2   |      1 |           200 |          500 |
+------+------+-----------+--------+---------------+--------------+

It's wrong. The Costs of cats id 1 is 300 but here I got 400

I Want Get Return From Query Like This:

+------+------+-----------+--------+---------------+--------------+
| c_id | p_id | c_name    | add_by | SUM(t.amount) | SUM(m.costs) |
+------+------+-----------+--------+---------------+--------------+
|    1 |    1 | Abhijit   |      1 |           100 |          300 |
|    2 |    1 | Abhiji2   |      1 |           200 |          500 |
+------+------+-----------+--------+---------------+--------------+

Upvotes: 0

Views: 78

Answers (2)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 522762

I think you had a typo (or error) in one of your JOIN conditions. I think you intended your original query to be this:

SELECT c.*, SUM(t.amount), SUM(m.costs)
FROM cats c
    LEFT JOIN meta m ON m.c_id = c.c_id
    LEFT JOIN transactions t ON t.m_id = m.c_id
GROUP BY c.c_id;

Note carefully ON t.m_id = m.c_id, which agrees with your expected output. In any case, I reworked your query as follows:

SELECT c.c_id, c.p_id, c.c_name, t2.transactionCosts, t1.metaCosts
FROM cats c
LEFT JOIN
(
    SELECT c_id, SUM(costs) AS metaCosts
    FROM meta
    GROUP BY c_id
) t1
    ON c.c_id = t1.c_id
LEFT JOIN
(
    SELECT m_id, SUM(amount) AS transactionCosts
    FROM transactions
    GROUP BY m_id
) t2
    ON c.c_id = t2.m_id
WHERE t2.transactionCosts IS NOT NULL OR t1.metaCosts IS NOT NULL;

The first subquery computes the meta total for each c_id, and the second subquery computes the transaction total for each m_id. These results are then both joined together with the cats table to get your final result.

Follow the link below for a running demo:

SQLFiddle

Upvotes: 1

Raffaello.D.Huke
Raffaello.D.Huke

Reputation: 552

the problem is you select c.* but only group by c_id, in this case you have 2 options. window function or subquery.

via over(partition by):

SELECT c.*, 
       SUM(t.amount)over(partition by c.c_id) as amount,
       SUM(m.costs)over(partition by c.c_id) as cost
FROM con_cats c
    LEFT JOIN meta m ON m.c_id=c.c_id
    LEFT JOIN transactions t ON t.m_id=m.m_id;

via subquery:

select a.*,b.amount,b.costs from con_cats a 
inner join
(SELECT c.c_id, SUM(t.amount) as amount, SUM(m.costs) as costs
FROM con_cats c
    LEFT JOIN meta m ON m.c_id=c.c_id
    LEFT JOIN transactions t ON t.m_id=m.m_id
GROUP BY c.c_id) b
on a.c_id = b.c_id;

Upvotes: 0

Related Questions