Reputation: 23
(I'm using postgres)
I've got two queries from different tables. Each is grouped by date. What is the best way to join them into one query (UNION or JOIN)? Thanks in advance.
Query №1:
SELECT to_char(date,'MM') as mon,
extract(year from date) as yyyy,
SUM("table_1"."user_money") AS user_sum,
SUM("table_1"."system_money") AS system_sum
FROM "table_1"
GROUP BY 1,2
ORDER BY 2,1;
Result for Query №1:
mon | yyyy | user_sum | system_sum
-----+------+------------------+-----------------
11 | 2015 | 10 | 50
12 | 2015 | 20 | 60
(2 rows)
Query №2:
SELECT to_char(created_at,'MM') as mon,
extract(year from created_at) as yyyy,
SUM("table_2"."amount") AS payments_sum
FROM "table_2"
GROUP BY 1,2
ORDER BY 2,1;
Result for Query №2:
mon | yyyy | payments_sum
-----+------+--------------
10 | 2015 | 500
11 | 2015 | 600
12 | 2015 | 700
01 | 2016 | 800
(4 rows)
Required result:
mon | yyyy | payments_sum | user_sum | system_sum
-----+------+--------------+------------------+----------------
10 | 2015 | 500 | |
11 | 2015 | 600 | 10 | 50
12 | 2015 | 700 | 20 | 60
01 | 2016 | 800 | |
(4 rows)
Upvotes: 2
Views: 1919
Reputation:
Try this.
SELECT
to_char(date,'MM') as mon,
extract(year from date) as yyyy,
SUM("table_2"."amount") AS payments_sum,
SUM("table_1"."user_money") AS user_sum,
SUM("table_1"."system_money") AS system_sum
FROM
"table_1"
LEFT JOIN
"table_2" ON (to_char("table_1"."date", 'MM') = to_char("table_2"."date", 'MM') AND extract(year from "table_1"."date") = extract(year from "table_2"."date"))
GROUP BY 1,2
ORDER BY 2,1;
Upvotes: 0
Reputation: 2630
Here is another one in a more PostgreSQL specific syntax:
WITH query_one AS (
SELECT
to_char(date,'MM') as mon,
extract(year from date) as yyyy,
SUM("table_1"."user_money") AS user_sum,
SUM("table_1"."system_money") AS system_sum
FROM
"table_1"
GROUP BY
1,2
), query_two AS (
SELECT
to_char(created_at,'MM') as mon,
extract(year from created_at) as yyyy,
SUM("table_2"."amount") AS payments_sum
FROM
"table_2"
GROUP BY
1,2
)
SELECT
*
FROM
query_one
LEFT JOIN query_two USING (mon, yyyy)
ORDER BY
yyyy
, mon;
The USING
clause is easier to use and prevents mon
and yyyy
to be twice in the output and the rest is just for the sake of a clear view.
Upvotes: 1
Reputation: 2723
I think you can treat each of your queries as a subquery and then combine with a full outer join. Union probably isn't what you want here.
Something like this:
SELECT * FROM
(SELECT to_char(date,'MM') as mon,
extract(year from date) as yyyy,
SUM("table_1"."user_money") AS user_sum,
SUM("table_1"."system_money") AS system_sum
FROM "table_1"
GROUP BY 1,2) AS q1
FULL OUTER JOIN
(SELECT to_char(created_at,'MM') as mon,
extract(year from created_at) as yyyy,
SUM("table_2"."amount") AS payments_sum
FROM "table_2"
GROUP BY 1,2) AS q2
ON q1.mon = q2.mon AND q1.yyyy = q2.yyyy
ORDER BY 2,1
joining where the mon and yyyy values match.
Upvotes: 0