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

时间:2012-01-03 15:59:08

标签: mysql sql count

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

文章位于包含以下字段的表格中

  • ITEM_ID
  • 标题
  • date_posted

blogposts 表格包含以下字段

  • ITEM_ID
  • 标题
  • date_posted

这两个表都有额外的字段。

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

表包含以下字段

  • ITEM_ID
  • SOURCE_ID
  • ...

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

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

4 个答案:

答案 0 :(得分:3)

你可以采取两种方式 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是索引中的 first 字段。另外,表格仍然需要重新排序以进行聚合。

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

我会使用不同的表格设计,包括类型和子类型。您的Items表有一个列主键,您的Blog_Posts和Articles表的主键是与Items表的外键相同的ID。这将使这样的事情变得非常容易,并且还有助于确保数据的完整性。

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

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'
    )

答案 3 :(得分:0)

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,所以它会更快(可能)。