简体   繁体   English

按日期将两个SQL表中的数据分组

[英]Group data by date from two SQL tables

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 下一部分将是从两个表中获取count(*)并将它们按上述查询的结果分组

  1. You need to use UNION ALL or the distinct aspect of union will eliminate the duplicates and negatively impact your counts. 您需要使用UNION ALL否则UNION ALL的独特之处将消除重复项并对您的计数产生负面影响。
  2. You need a way to denote which value is from what table so we add a column to distinguish, so I added 1 for tbl1 and 2 for tbl2 and called the column src. 您需要一种方法来指示哪个值来自哪个表,因此我们添加了一个列来进行区分,因此我为tbl1添加了1,为tbl2添加了2,并将其称为src列。
  3. We then add a case statement in the outer select and a sum to get the desired counts and a group by to aggregate the dates.. 然后,我们在外部select中添加一个case语句和一个总和以获取所需的计数,并在group by上汇总日期。
  4. Polish it off with an order by and you get what you're after. 通过下订单将其擦亮,您将得到想要的东西。

.

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

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. 然后,您可以进行FULL OUTER联接以获得所有配对。 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: MySQL没有内置的完整联接,但是您可以使用右联接和左联接的联合来模拟它,请尝试以下操作:

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. 这是一个SQL Fiddle示例。

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. union distinct很好,并且实际上是我们所希望的,我们只需要确保包含足够的列即可使区别选择准确地满足我们的需求。

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 演示在这里: http : //sqlfiddle.com/#!9/eaa3b/21

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: 我认为最有效的方法是进行两个查询:一个查询来自table1的所有分组日期并将table2的计数设置为0,另一个查询来自table2的所有分组日期并将table1的计数设置为0,然后合并使用UNION ALL查询对它们进行重新分组,然后对结果计数求和:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM