2017-02-28 76 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