MySQL实现按天分组统计,提供完整日期列表,无数据自动补0

业务需求

最近要在PHP+MySQL的老系统中加个统计功能,要求是按指定日期范围里按天分组统计数据量,并且要能够查看该时间段内每天的数据量。

解决思路

直接按数据表日期字段group by统计,发现如果某天没数据,该日期是不出现的,这不太符合业务需求。百度一番发现方案大致有两种:一是新建日期列表,把未来10年的日期放进去,然后再跟统计表作连接查询;二是用程序代码在SQL逻辑中union多个连续日期查询。都比较繁琐。
参考Oracle的“select level from dual connect by level < 31”的实现思路:
1、先用一个查询把指定日期范围的日期列表搞出来

SELECT @cdate:= date_add(@cdate,interval - 1 day) as date_str , 0 as date_count
FROM (SELECT @cdate:=date_add(CURDATE(),interval + 1 day) from 数据库随便个有数据的表名) t1
where @cdate > ‘2018-12-01’ and @cdate < ‘2018-12-31’

2、业务统计查询也按上述日期查询给统计日期和数量设置别名

SELECT FROM_UNIXTIME(m.时间戳字段, ‘%Y-%m-%d’) as date_str , count(*) as date_count
from 业务数据表名 as m
group by FROM_UNIXTIME(m.时间戳字段, ‘%Y-%m-%d’)

3、把两个查询用左连接合起,没数量的日期填0,完工

SELECT t1.date_str , COALESCE(t2.date_total_count,0) as date_total_count
FROM(
SELECT @cdate:= date_add(@cdate,interval - 1 day) as date_str
FROM (SELECT @cdate:=date_add(CURDATE(),interval + 1 day) from 业务数据表名) tmp1
WHERE @cdate > ‘2018-12-01’
) t1
LEFT JOIN(
SELECT FROM_UNIXTIME(m.时间戳字段, ‘%Y-%m-%d’) as date_str , count(*) as date_total_count
FROM 业务数据表名 as m
WHERE m.时间戳字段 between XXXX and XXXXX
GROUP BY FROM_UNIXTIME(m.时间戳字段, ‘%Y-%m-%d’)
) t2
on t1.date_str = t2.date_str

查询结果如下图所示:
在这里插入图片描述

Logo

更多推荐