Reputation: 2465
Consider the following tables:
tbl1
------------
id name creationdate
0 AA 2015.05.11
1 BB 2015.04.27
2 cC 2015.04.18
tbl2
------------
id name creationdate
0 DD 2015.04.17
1 FF 2015.04.27
2 NN 2015.05.01
3 BV 2015.05.01
What would be the correct syntax for a query to group the count of rows from both table by dates? So that the result is:
DATE TBL1_COUNT TBL2_COUNT
2015.04.17 0 1
2015.04.18 1 0
2015.04.27 1 1
2015.05.01 0 2
2015.05.11 1 0
So far I have managed to get the dates from both tables using:
select DISTINCT date(creationdate) from tbl1
union
select DISTINCT date(creationdate) from tbl2
The next part would be getting count(*) from both tables and grouping them by the above query's result
Upvotes: 1
Views: 76
Reputation: 35323
UNION ALL
or the distinct aspect of union will
eliminate the duplicates and negatively impact your counts..
SELECT creationDate as Date,
sum(case when src=1 then 1 else 0 end) as tbl1_count,
sum(case when src=2 then 1 else 0 end) as tbl2_count
FROM (
SELECT creationdate, 1 as src
FROM tbl1
UNION ALL
SELECT creationdate, 2 as src
FROM tbl2) Sub
GROUP BY CreationDate
ORDER BY CreationDate
Upvotes: 3
Reputation: 49049
I think the most efficient way is to have two queries: one that counts all grouped dates from table1 and set the count of table2 to 0, one other that counts all grouped dates from table2 and sets the count of table1 to 0, and then combine them using a UNION ALL query, group again and sum the resulting counts:
SELECT creationDate, sum(count_t1), sum(count_t2)
FROM (
SELECT creationDate, COUNT(*) AS count_t1, 0 AS count_t2
FROM t1
GROUP BY creationDate
UNION ALL
SELECT creationDate, 0 AS count_t1, COUNT(*) AS count_t2
FROM t2
GROUP BY creationDate
) s
GROUP BY creationDate
Upvotes: 1
Reputation: 9010
You can simluate a full outer join, basically. union distinct
is fine, and actually desired, we just have to make sure we include sufficient columns to allow the distinct selection to be accurate to our needs.
select d3, count(d1), count(d2)
from (
select t1.id id1, t2.id id2, t1.date as d1, t2.date as d2, coalesce(t1.date, t2.date) d3
from tbl1 t1
left join tbl2 t2
on t1.date = t2.date
union
select t1.id id1, t2.id id2, t1.date as d1, t2.date as d2, coalesce(t1.date, t2.date) d3
from tbl1 t1
right join tbl2 t2
on t1.date = t2.date
) q
group by d3;
Demo here: http://sqlfiddle.com/#!9/eaa3b/21
Upvotes: 1
Reputation: 16691
You have a good start. If I were approaching this, I would start by getting a date and count from each table, like this:
SELECT creationDate, COUNT(*) AS numRows
FROM t1
GROUP BY creationDate;
Then, you can do a FULL OUTER join to get all pairings. MySQL doesn't have full join built in, but you can emulate it using a union of a right join and a left join, try this:
SELECT t1.creationDate, t1.numRows AS t1Rows, COALESCE(t2.numRows, 0) AS t2Rows
FROM(
SELECT creationDate, COUNT(*) AS numRows
FROM t1
GROUP BY creationDate) t1
LEFT JOIN(
SELECT creationDate, COUNT(*) AS numRows
FROM t2
GROUP BY creationDate) t2 ON t1.creationDate = t2.creationDate
UNION
SELECT t2.creationDate, COALESCE(t1.numRows, 0) AS t1Rows, t2.numRows AS t2Rows
FROM(
SELECT creationDate, COUNT(*) AS numRows
FROM t1
GROUP BY creationDate) t1
RIGHT JOIN(
SELECT creationDate, COUNT(*) AS numRows
FROM t2
GROUP BY creationDate) t2 ON t1.creationDate = t2.creationDate;
Here is an SQL Fiddle example.
Upvotes: 2