2017-02-28 38 views
1

我正在編寫一個用Laravel 5.2編寫的項目,該項目有兩個表,需要查詢這兩個表以生成按年創建的記錄數摘要。下面是該架構的簡化佈局與一些樣本數據:Laravel 5.2中的MySQL摘要查詢

事項表

id created_at 
----------------- 
1 2016-01-05 10:00:00 
2 2016-03-09 11:00:00 
3 2017-01-03 10:00:00 
4 2015-05-06 11:00:00 

說明表

id created_at 
----------------- 
1 2015-07-08 10:00:00 
2 2016-03-16 11:00:00 
3 2017-09-03 10:00:00 
4 2017-11-06 11:00:00 

每個表都有幾十萬條記錄,所以我想成爲能夠(有效地)查詢我的數據以產生以下結果,每個表的計數按年份計算:

year matters  notes 
---------------------------- 
2015 1   1 
2016 2   1 
2017 1   2 

我需要每列可排序。目前,我能想到的做到這一點,最快的方法就是有兩個查詢,如以下內容,然後通過PHP結合兩種結果:

SELECT YEAR(matters.created_at) AS 'year', COUNT(1) AS 'matters' 
FROM matters 
GROUP BY YEAR(matters.created_at) 


SELECT YEAR(notes.created_at) AS 'year', COUNT(1) AS 'notes' 
FROM notes 
GROUP BY YEAR(notes.created_at) 

但我不知道是否有更好的方法,特別是因爲我必須根據用戶的需求對每列進行排序。

有什麼想法?

回答

1

year位可以被用於創建表之間的JOIN(以及它們各自的結果集合)以產生組合的輸出,可以進一步通過選擇的任何領域進行排序:

SELECT t1.year_rec, IFNULL(t1.matters, 0) AS matters, IFNULL(t2.notes, 0) AS notes 
FROM 
    (
     SELECT DATE_FORMAT(created_at, "%Y") AS year_rec, COUNT(id) AS matters 
      FROM matters 
     GROUP BY year_rec 
    ) t1 
    LEFT JOIN 
    (
     SELECT DATE_FORMAT(created_at, "%Y") AS year_rec, COUNT(id) AS notes 
      FROM notes 
     GROUP BY year_rec 
    ) t2 
ON t1.year_rec = t2.year_rec 
-- ORDER BY -- 

Demo

警告:

銘記的JOIN s以及自然MySQL不provi如果直接寫FULL OUTER JOIN,你會注意到如果某個year在第一個表中沒有任何參與LEFT JOIN的記錄,那麼這個year將從最終輸出中被省略。如果我們將查詢更改爲RIGHT JOIN,那麼將根據第二個表執行省略操作。但是,如果這種情況不會發生在你的情況下(即,如果你認爲在這兩個表格中每一個year都會有記錄),那麼你不必擔心這種情況,但它仍然是很好的意識到這個漏洞。

欲瞭解更多信息:Full Outer Join in MySQL

+0

謝謝!這正是我所期待的。我忘記了你可以加入格式化爲一年的日期。謝謝! – BakerStreetSystems