当count为0时,MySQL每天计数

时间:2011-08-30 08:55:13

标签: php mysql sql timestamp

我有一个MySQL查询:

SELECT COUNT(*) AS total,  DATE_FORMAT(event.serverTime,'%Y-%m-%d') AS sdate
                    FROM event
                    WHERE
                    event.serverTime >= :startDate
                    AND event.serverTime <= :endDate 
                    GROUP BY sdate;

正确返回的内容如下:

2011-08-10 => 5  
2011-08-15 => 6

但是,我想得到0计数的日期。所以假设startDate是2011-08-10而endDate是2011-08-15,我会看到:

2011-08-10 => 5  
2011-08-11 => 0  
2011-08-12 => 0  
2011-08-13 => 0  
2011-08-14 => 0  
2011-08-15 => 6

我正在使用PHP,所以理论上我可以做一些复杂的循环并以某种方式填补空白,但我想知道是否有更好的解决方案?

请注意,如果不存在良好的MySQL解决方案,我也会接受良好的PHP解决方案

3 个答案:

答案 0 :(得分:2)

如果您希望每天计数项目的结果为0,

试试这个:

set @date_start := (SELECT MIN(date_col) FROM my_table), 
    @date_end := (SELECT MAX(date_col) FROM my_table), 
    @i := 0;
SELECT DATE(ADDDATE(@date_start, INTERVAL @i:=@i+1 DAY)) AS date,
IFNULL((
    SELECT COUNT(*) FROM my_table AS m2
    WHERE DATE(m2.date_col) = DATE(ADDDATE(@date_start, INTERVAL @i DAY))
),0) AS total
FROM my_table AS m1
HAVING @i < DATEDIFF(@date_end, @date_start)

输出:

[
    {
        "date": "2017-03-01",
        "total": "0"
    },
    {
        "date": "2017-03-02",
        "total": "0"
    },
    {
        "date": "2017-03-03",
        "total": "0"
    },
    {
        "date": "2017-03-04",
        "total": "0"
    },
    {
        "date": "2017-03-05",
        "total": "0"
    }
]

答案 1 :(得分:1)

我认为你可以寻找的一个可能的解决方案是创建一个填充了所有日期的表,然后与表连接。表不会很大,因为它只包含365行一年。预计此表并加入此表以供查询。

这里的好处是,每次调用此查询时,您都不会在php中执行任何复杂的日期循环。你填充了一次你的桌子并一遍又一遍地使用它。

答案 2 :(得分:0)

您需要创建一个包含日期的表格并加入其中。

table temp_dates
id integer auto_increment PK
mydate date  <<-- consecutive dates

现在执行以下查询

SELECT count(e.servertime) as total
       , td.mydate as sdate
FROM event e
RIGHT JOIN temp_dates td ON (td.mydate = date(e.servertime))
WHERE td.mydate BETWEEN :startdate AND :enddate
GROUP BY td.mydate 
HAVING total = 0