2012-01-03 85 views
1

我的數據庫中有新聞文章和博客文章。兩者的主鍵都是在兩個表中唯一的ItemID。在多個表中按日期分組的Mysql計數記錄

文章是在具有以下字段

  • ITEM_ID
  • 標題
  • date_posted

的相關博客文章表具有以下的表字段

  • ITEM_ID
  • 標題
  • date_posted

兩個表具有獨特他們額外的字段。

我有第三個表,包含關於文章和帖子的元信息。

項目表具有以下字段

  • ITEM_ID
  • SOURCE_ID
  • ...

每一個博客帖子和文章在項目表和記錄的記錄在各自的表格中。

我想要做的是構建一個查詢,將計算每天張貼的項目數量。我可以使用按日期分組計數的一張表執行此操作,但如何在一個查詢中將合併文章和帖子計數爲

回答

2

類似民主黨,但稍微簡單:

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

+1:我無法在MySQL上測試,但在SQL Server上測試時,它的優化效果非常好(我沒有預計) – MatBailie 2012-01-03 16:42:57

+1

***注意:***同樣假設索引與'date_posted'作爲第一個領域的最佳性能。 – MatBailie 2012-01-03 16:43:37

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

+0

我試圖做一個工會,但什麼其實我試圖做的,這不是在OP明確的是計數的結果結合起來。所以這兩個選擇是'select count(item_id)from blogposts group by date'和'select count(item_id_ from articles group by date') – applechief 2012-01-03 16:16:42

1

我會用這個不同的表設計,類型和子類型。 Your 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

你能做到的兩種方式。
1.加入所有內容,然後彙總(請參閱Tom H的回答)。
2.聚合每個表,將它們聯合起來,然後重新聚合。

選項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是該指數第一場。否則,表格仍然需要重新排序才能進行彙總。

+0

只需記住第二個解決方案,即某些聚合有點複雜。例如(平均值),但這是一個很好的解決方案 – 2012-01-03 19:25:43

+0

是一個「小」的技巧,是的,但是因爲你可以返回SUM(value)和COUNT(*),所以你可以做平均值,你甚至可以做STDev如果數據格式合適,Mark Ba​​nnister的答案更簡單: – MatBailie 2012-01-03 19:40:58