首先按时时间分组的常规方法是
select count(1) count,DATE_FORMAT(create_time,'%Y-%m') month from sys_course where school_id=0 group by month
执行结果
返回的结果,在时间上不是连续的,如果是在绘图制表业务中,不连续的日期肯定是不行的
下面先展示下改进后的sql
selectIFNULL(data.count,0),month_list.monthsfrom(select count(1) count,DATE_FORMAT(create_time,'%Y-%m') months from sys_user where school_id=0 GROUP BY months) dataright join (SELECT DATE_FORMAT(@date := DATE_ADD(@date, interval -1 month),'%Y-%m') months from (SELECT @date := DATE_ADD(CURDATE(), interval -1 month) from sys_user) months limit 6) month_list on data.months=month_list.months
执行结果
先普及一个知识,在mysql里:
= 和 := 的区别:
在update和set的时候没有区别,都是赋值的作用。:= 在select里也可以作为赋值来用。
所以分析sql:左边是具体的业务数据,右边是时间列表,我这里是取的开始时间升序排列,也可以填结束时间,然后降序排列。
主要说右边时间列表部分:先说第二个@date,这里是读取实际的业务表,然后在此同时给@date变量赋值,具体的值为我写入的规则,也就是我的查询开始时间的前一天,为什么这么写呢,因为在第一个@date那里要开始往后推导日期,为了将开始时间也推导出来,所以需要将这个起始选到前一天。需要注意的是,业务表总数据量应该大于要查询的天数,以便给变量赋值时候能对应上,否则可能会出现天数不够的情况。
这是执行查询业务表并给变量赋值的结果,这里的条数是该业务表的条数,可以 limit 你需要的条数。此时会得到一个临时表,然后通过再一次的select 变量赋值的方法,select @date := 这个语法会对date变量赋值,比如第一个值会在dateadd函数下加一天变为,2023-01,此时@date变量也被赋予此值,在读取第二个值并赋值时,第二个值会变为2022-12,以此类推。即可得到我们想要的结果。
此时获取到想要的时间列表,然后跟实际的业务数据进行关联,让时间相等即可,此时可得到完整的时间对应数据关系,在实际业务数据里没有的日期则为空,我们置为0即可。
本文参考地址:https://blog.csdn.net/qq_39314099/article/details/90667087
来源地址:https://blog.csdn.net/weixin_44740485/article/details/129360239