繁体   English   中英

MySQL计数记录按天分组在多个表中

[英]Mysql count records grouped by day in multiple tables

我的数据库中有新闻文章和博客文章。 两者的主键都是在两个表中唯一的ItemID。

文章在具有以下字段的表中

  • item_id
  • 标题
  • 身体
  • 发布日期

Blogposts表具有以下字段

  • item_id
  • 标题
  • 身体
  • 发布日期

两个表都有它们唯一的额外字段。

我有第三个表,其中包含有关文章和帖子的元信息。

项目表具有以下字段

  • item_id
  • source_id
  • ...

每个博客文章和文章在items表中都有一条记录,在其各自的表中都有一条记录。

我想做的是建立一个查询,该查询将计算每天发布的项目数。 我可以使用按date_posted分组的计数对一个表执行此操作,但是如何在一个查询中合并文章和计数

您可以通过两种方式做到这一点。
1.将所有内容结合在一起,然后汇总(请参阅Tom H的答案)。
2.汇总每个表,对其进行UNION,然后再次进行汇总。

选项1可能看起来更短,但将意味着您可能无法从根表上的INDEX中受益(因为必须对JOIN对其进行重新排序)。 因此,我将显示选项2,它是您前进的方向。

SELECT
  date_posted,
  SUM(daily_count) AS daily_count
FROM
  (
   SELECT date_posted, COUNT(*) AS daily_count FROM article   GROUP BY date_posted
   UNION ALL
   SELECT date_posted, COUNT(*) AS daily_count FROM blogposts GROUP BY date_posted
  )
  AS combined
GROUP BY
  date_posted

如果您在每个表上都有一个索引,而date_posted是索引中的第一个字段,则这应该是最快的。 否则,仍将需要对表进行重新排序以进行聚合。

与Dems类似,但稍微简单一些:

select date_posted, count(*)
from (select date_posted from article union all
      select date_posted from blogposts) v
group by date_posted

我将为此使用不同的表设计,包括类型和子类型。 您的Items表只有一个单列主键,而Blog_Posts和Articles表的主键是相同的ID,并带有Items表的外键。 这样可以很容易地做到这一点,并有助于确保数据完整性。

使用您现有的设计,最好的选择可能是这样的:

SELECT
    I.item_id,
    I.source_id,
    COALESCE(A.date_posted, B.date_posted) AS date_posted,
    COUNT(*) AS date_count
FROM
    Items I
LEFT OUTER JOIN Articles A ON
    A.item_id = I.item_id AND
    I.source_id = 'A'  -- Or whatever the Articles ID is
LEFT OUTER JOIN Blog_Posts B ON
    B.item_id = I.item_id AND
    I.source_id = 'B'  -- Or whatever the Blog_Posts ID is
GROUP BY
    I.item_id,
    I.source_id,
    COALESCE(A.date_posted, B.date_posted)

您也可以尝试使用UNION

SELECT
    SQ.item_id,
    SQ.source_id,
    SQ.date_posted,
    COUNT(*) AS date_count
FROM
    (
        SELECT I1.item_id, I1.source_id, A.date_posted
        FROM Items I1
        INNER JOIN Articles A ON A.item_id = I1.item_id
        WHERE I1.source_id = 'A'
        UNION ALL
        SELECT I2.item_id, I2.source_id, B.date_posted
        FROM Items I2
        INNER JOIN Articles B ON B.item_id = I2.item_id
        WHERE I2.source_id = 'B'
    )
select item_id, date_posted from blogposts where /* some conditions */
union all select item_id, date_posted from articles where /* some conditions */

您可能需要将其放入子查询中,如果需要,在运行group by时将其与其他表连接。 但是最主要的是, union是用于合并来自不同表的数据的运算符。 union all告诉数据库您不需要它来合并重复的记录,因为您知道两个表永远不会共享item_id,所以它快了一点(可能)。

暂无
暂无

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

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