实现目标及最初的想法
主要是项目中要使用到统计每天的用户增加总数,想用echarts图标展现出来,最初的sql是这样写的
// me_user 用户表 create_date 用户创建日期 day 传入的时间间隔(表示查询从现在起往前多少天)
SELECT COUNT(*) AS num,create_date AS date
FROM me_user GROUP BY create_date ORDER BY create_date ASC limit #{day}
发现问题
最开始觉得没有问题,但过几天后来看是这样的:
很明显,中间没有用户的十天(还在测试阶段~)我希望它是零,而不是没有,那能不能用万能的sql来解决而不是逻辑层用for循环呢?
解决办法
不多说,先上代码:
SELECT dayTb.cday '日期',IFNULL(tNumTb.num ,0) '人数'
FROM (
SELECT @cdate := DATE_ADD(@cdate, INTERVAL +1 DAY) cday
FROM( SELECT @cdate := DATE_ADD(CURDATE(), INTERVAL -7 DAY) FROM me_user LIMIT 15) t0
WHERE DATE(@cdate) <= DATE_ADD(CURDATE(), INTERVAL -1 DAY)
) dayTb
LEFT JOIN(
SELECT DATE(t.create_date) cday,COUNT( t.id ) num FROM me_user t
WHERE t.create_date >=DATE_ADD(CURDATE(), INTERVAL -7 DAY)
GROUP BY cday
) tNumTb ON tNumTb.cday = dayTb.cday
主要思路:主要是用
SELECT @cdate := DATE_ADD(@cdate, INTERVAL +1 DAY) cday
FROM( SELECT @cdate := DATE_ADD(CURDATE(), INTERVAL -7 DAY) FROM me_user LIMIT 15) t0
WHERE DATE(@cdate) <= DATE_ADD(CURDATE(), INTERVAL -1 DAY)
这里主要是以me_user表为载体,执行这一条查询语句,载体可以随你换
不过注意一点,你的表里需要有足够多的数据,比如你生成7天的数据,载体表里就必须有>7条的数据
生成一个最近七天的日期表
然后外连接me_uer表(当然这里只需要连接查出create_date那一列就好啦~),最后用SQL的IFNULL(tNumTb.num ,0) 函数将null的值赋为0就搞定了。
PS:持久层用的mybatis,这里附一段mybatis的实现
<select id="userRemainWeek" resultType="map">
SELECT dayTb.cday date,IFNULL(tNumTb.num ,0) num
FROM (
SELECT @cdate := DATE_ADD(@cdate, INTERVAL +1 DAY) cday
FROM( SELECT @cdate := DATE_ADD(CURDATE(), INTERVAL -#{day} DAY) FROM
me_user LIMIT 15) t0
WHERE DATE(@cdate) <= DATE_ADD(CURDATE(), INTERVAL -1 DAY)
) dayTb
LEFT JOIN(
SELECT DATE(t.create_date) cday,COUNT( t.id ) num FROM me_user t
WHERE t.create_date >= DATE_ADD(CURDATE(), INTERVAL -#{day} DAY)
GROUP BY cday
) tNumTb ON tNumTb.cday = dayTb.cday
</select>
最终结果:
结语
SQL其实非常强大,熟练使用SQL语句可以让我们在开发过程中省去很多的麻烦事儿!
人生第一篇博客,记录一下~~~
——JAVA开发