mysqljoincartesian

Sum two columns from two tables without cartesian


I searched for a while but nothing I find fixes my problem...

I have two tables: earnings, expenses

I have the columns:

I want to sum the amount of all my earnings and show them by year and month, so I do this and it works perfectly...

SELECT
     DATE_FORMAT(date, '%Y%m') AS 'date',
     SUM(amount) as 'total_earnings'
FROM earnings
GROUP BY DATE_FORMAT(date, '%Y%m')

The output is similar to this...

date,total_earnings
201901,5000
201902,5500
201903,6200
etc.

I do the same for the expenses table and all is well.

My problem: When I try to write a query that shows me total earnings and total expenses grouped by year and month I get a cartesian result that shows huuuge numbers.

This is an example query that shows a cartesian result:

SELECT
    DATE_FORMAT(ea.date, '%Y%m') AS date,
    SUM(ea.amount) AS 'total_earnings',
    SUM(ex.amount) AS 'total_expenses',
FROM earnings ea
    INNER JOIN expenses ex
        ON DATE_FORMAT(ea.date, '%Y%m') = DATE_FORMAT(ex.date, '%Y%m')
GROUP BY DATE_FORMAT(ex.date, '%Y%m')

How can I show the total amount of monthly earnings and monthly expenses in a single query?

Desired output:

date,total_earnings,total_expenses
201901,5000,1000
201902,5500,1100
201903,6200,1250

Thanks in advance!


Solution

  • You need to aggregate first, then JOIN

    SELECT ea.date, total_earnings, total_expenses
    FROM (
        SELECT DATE_FORMAT(date, '%Y%m') AS date
            , SUM(amount) AS total_earnings
        FROM earnings 
        GROUP BY DATE_FORMAT(date, '%Y%m')
    ) ea
    JOIN (
        SELECT DATE_FORMAT(date, '%Y%m') AS date
            , SUM(amount) AS total_expenses
        FROM expenses
        GROUP BY DATE_FORMAT(date, '%Y%m')
    ) ex ON ex.date = ea.date