mysql按⽇期分组(groupby)查询统计的时候,没有数据补0
的解决办法
1、案例中的数据结构和数据如下
2、在没有解决的时候,是这样的
SELECT date(downtime) AS dday, count(*) AS num FROM re_device GROUP BY dday
groupby分组得到如下结果,如果那天没有数据,那麽就会没有记录
我们看到,时间不连续,没有2016-3-05这⼀天的,这样本来不是问题,但是,我拿出来的数据,还要画出图表呀,没有当然不⾏,我们需要的是下⾯这个样⼦的。
简单的说就是,没有数据,就要补充⼀个0.
3、下⾯我们讲实现
我们要⽣成⼀个⽇历的表,然后和原来的数据,联合查询,说到这⾥,⼤家就知道很low了,但是,限于我⽔平有限,研究这个问题,半天,这个是我到的⽐较好的⼀种实现⽅式。如果你⼜更好的,也请你给我说下。
执⾏下⾯的sql,直接诶⽣成⽇历的表(calendar)
CREATE TABLE num (i int);-- 创建⼀个表⽤来储存0-9的数字
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);-- ⽣成0-9的数字,⽅便以后计算时间CREATE TABLE if not exists calendar(datelist date); -- ⽣成⼀个存储⽇期的表,datalist是字段名
-- 这⾥是⽣成并插⼊⽇期数据
INSERT INTO calendar(datelist) SELECT
adddate(
( -- 这⾥的起始⽇期,你可以换成当前⽇期
DATE_FORMAT("2016-1-1", '%Y-%m-%d')
),
numlist.id
) AS `date`
FROM
(
SELECT
n1.i + n10.i * 10 + n100.i * 100 + n1000.i * 1000+ n10000.i * 10000 AS id
FROM
num n1
CROSS JOIN num AS n10
CROSS JOIN num AS n100
CROSS JOIN num AS n1000
CROSS JOIN num AS n10000
) AS numlist;
这⾥我⽤了100000条记录,算出来到2289年了,完全够⽤了,到那个时候,出问题,我也管不了了。完成之后,请删除num的零时表
4、联合查询
SELECT
date(dday) ddate,
count(*) - 1 as num
FROM
(
SELECT
datelist as dday
FROM
calendar
-- 这⾥是限制返回最近30天的数据
where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(datelist)&&date(datelist)<=CURDATE() UNION ALL
SELECT
downtime
FROM
re_device
) a
GROUP BY ddate
好了,到这⾥,基本就完成了这个查询,出来的数据,我还是⽐较满意的。
5、其他解决⽅法
当然,应该还有其他的解决⽅案,但是博主就没有去写了,有时间可以去写⼀下。
我⽤的spring mvc,所以,也还是可以在java代码中补充完整的,因为数据返回的是个map对象,那麽我们要遍历这个对象,直接⽤calendar对象,⽣成⽇期作为key来遍历,如果没有数据,就put进去⼀个0,然后在限制⼀下,需要多少天的,就可以了。数据就完整了。但是这样也有⼀个问题,那就是map⾥的数据顺序会有问题,所以,使⽤的时候,也必须是⽣成calendar对象,然后构造出来⽇期作为key 来遍历。或者⽤Collections.sort()排序⼀下。
我个⼈觉得,还是上数据直接⽣成得⽐较好⼀点。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论