繁体   English   中英

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

[英]Group data by date from two SQL 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

查询将两个表中的行数按日期分组的正确语法是什么? 这样的结果是:

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

到目前为止,我已经设法使用以下命令从两个表中获取日期:

select  DISTINCT date(creationdate) from tbl1
union
select  DISTINCT date(creationdate) from tbl2

下一部分将是从两个表中获取count(*)并将它们按上述查询的结果分组

  1. 您需要使用UNION ALL否则UNION ALL的独特之处将消除重复项并对您的计数产生负面影响。
  2. 您需要一种方法来指示哪个值来自哪个表,因此我们添加了一个列来进行区分,因此我为tbl1添加了1,为tbl2添加了2,并将其称为src列。
  3. 然后,我们在外部select中添加一个case语句和一个总和以获取所需的计数,并在group by上汇总日期。
  4. 通过下订单将其擦亮,您将得到想要的东西。

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

您有一个好的开始。 如果要解决这个问题,我将从每个表中获取日期和计数开始,如下所示:

SELECT creationDate, COUNT(*) AS numRows
FROM t1
GROUP BY creationDate;

然后,您可以进行FULL OUTER联接以获得所有配对。 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;

这是一个SQL Fiddle示例。

基本上,您可以模拟完整的外部联接。 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;

演示在这里: http : //sqlfiddle.com/#!9/eaa3b/21

我认为最有效的方法是进行两个查询:一个查询来自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