简体   繁体   English

MySQL计数包括不在日期范围内的月份

[英]MySQL Count that includes months not within the date range

Supposed I have a table that contains the following table: 假设我有一个包含以下表的表:

+----+-----------+---------+-------------------------+
| id |  item     |  ....   | dateLogged              |
+----+-----------+---------+-------------------------+
|  1 | 2015-001  |  ....   | 2015-06-01 12:09:00     |
|  2 | 2015-001  |  ....   | 2015-06-01 12:09:00     |
|  3 | 2015-002  |  ....   | 2015-06-30 15:40:02     |
|  4 | 2015-002  |  ....   | 2015-06-30 15:40:03     |
|  5 | 2015-003  |  ....   | 2015-07-02 13:38:22     |
+----+-----------+---------+-------------------------+

I want to search the number of items based on the year, month and count from the dateLogged, with the expected data: 我想根据年份,月份从dateLogged中搜索项目数,并使用预期数据:

+--------+----------+----------------+
| year   |  month   |     total      | 
+--------+----------+----------------+
|  2015  | January  |      0         | 
|  2015  | February |      0         | 
|  2015  | March    |      0         | 
|  2015  | April    |      0         | 
|  2015  | May      |      0         | 
|  2015  | June     |      4         | 
|  2015  | July     |      1         | 
|  2015  | August   |      0         | 
|  2015  | September|      0         | 
|  2015  | October  |      0         | 
|  2015  | November |      0         | 
|  2015  | December |      0         |
+--------+----------+----------------+

But I am only getting this based on the following SQL: 但是我只能基于以下SQL来获取它:

SELECT DATE_FORMAT(dateLogged, '%Y') as 'year', MONTHNAME(dateLogged) 
as 'month', COUNT(id) as 'total' from item a where dateLogged >= '2015-06-29 00:00:00' 
and dateLogged <= '2015-07-02 23:59:59' 
GROUP BY DATE_FORMAT(a.dateLogged, '%Y%m');

+--------+---------+----------------+
| year   |  month  |  No of items   | 
+--------+---------+----------------+
|  2015  | June    |      4         | 
|  2015  | July    |      1         | 
+----+-------------+----------------+    

I've tried searching elsewhere from stackoverflow, but wasn't able to get any answers, or probably have missed. 我曾尝试从stackoverflow的其他位置进行搜索,但无法获得任何答案,或者可能错过了。 Wanna know if there is any solution to this, thanks. 想知道是否有任何解决方案,谢谢。

I am using Java to compute this, so any suggestions using Java to compute the above is also welcomed. 我正在使用Java进行计算,因此也欢迎使用Java进行上述计算的任何建议。

You could change your query to return the 0 values as well using loops to iterate over months and years and then find the count. 您也可以使用循环迭代数月和数年然后查找计数,来更改查询以返回0值。 Something like this: 像这样:

Map<String, Integer> values = new HashMap<String, Integer>();
for(int year = 2015; year < 2017; year++)
{
    for(int month = 1; month <= 12; month++)
    {
        rs = stmt.executeQuery("SELECT COUNT(id) as 'total' from item where
                 MONTH(dateLogged) = " + month + " and YEAR(dateLogged) = " + year + ";";
        rs.next();
        int count = rs.getInt("total");
        String time = Integer.toString(year) + "-" + Integer.toString(month);
        values.Add(time, count);
    }
}

This would return you a map like this: 这将为您返回如下地图:

values['2015-1'] = 0;
values['2015-2'] = 0; 

.. and so on. .. 等等。

Of course, you could store the returned count with year and month however you want, depending on how you wish to use it further. 当然,您可以根据需要将返回的计数与年和月一起存储,具体取决于您希望如何进一步使用它。

One idea is to, somehow, create a calendar table, and use it, so that you get a row for each month of year 2015: 一个想法是以某种方式创建日历表并使用它,以便您在2015年的每个月都有一行:

SELECT DATE_FORMAT(m, '%Y') as 'year', 
       MONTHNAME(m) as 'month',
       COUNT(id) as 'total' 
FROM (SELECT '2015-01-01' AS m UNION ALL SELECT '2015-02-01' UNION ALL
      SELECT '2015-03-01' UNION ALL SELECT '2015-04-01' UNION ALL 
      SELECT '2015-05-01' UNION ALL SELECT '2015-06-01' UNION ALL 
      SELECT '2015-07-01' UNION ALL SELECT '2015-01-08' UNION ALL 
      SELECT '2015-09-01' UNION ALL SELECT '2015-10-01' UNION ALL 
      SELECT '2015-11-01' UNION ALL SELECT '2015-12-01') AS x
LEFT JOIN item a 
ON DATE_FORMAT(a.dateLogged, '%Y%m') = DATE_FORMAT(x.m, '%Y%m') 
   AND dateLogged >= '2015-06-29 00:00:00' 
   AND dateLogged <= '2015-07-02 23:59:59' 
GROUP BY DATE_FORMAT(x.m, '%Y%m');

The above query makes use of sort of an inline calendar table for year 2015. This table is used as a basis in the FROM clause, so that the query returns a row for each of the months of year 2015. 上面的查询利用排序此表用作一个基础,2015年的在线日历表的FROM子句,因此该查询返回每个 2015年的几个月内排。

Demo here 在这里演示

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

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