第一种思路
首先需要一张临时表来作为基础,辅助我们去真正的表里捞数据
实践
- curdate()函数
SELECT curdate()
如果我们想要昨天的日期怎么办呢?
- DATE_SUB(date,INTERVAL expr type)函数
date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。
| type值 |
|---|
| MICROSECOND |
| SECOND |
| MINUTE |
| HOUR |
| DAY |
| WEEK |
| MONTH |
| QUARTER |
| YEAR |
| SECOND_MICROSECOND |
| MINUTE_MICROSECOND |
| MINUTE_SECOND |
| HOUR_MICROSECOND |
| HOUR_SECOND |
| HOUR_MINUTE |
| DAY_MICROSECOND |
| DAY_SECOND |
| DAY_MINUTE |
| DAY_HOUR |
| YEAR_MONTH |
SELECT date_sub(curdate(), interval 1 day)
- union关键字
我们可以吧多个结果合并在一起 演示如下:
SELECT curdate() as currentdate
union all
SELECT date_sub(curdate(), interval 1 day) as currentdate
union all
SELECT date_sub(curdate(), interval 2 day) as currentdate
union all
SELECT date_sub(curdate(), interval 3 day) as currentdate
- 建个订单表
CREATE TABLE `test_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(11) DEFAULT NULL,
`order_num` int(11) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
插入数据
INSERT INTO test_order(item_id,order_num) VALUES (1,1);
INSERT INTO test_order(item_id,order_num) VALUES (2,2);
INSERT INTO test_order(item_id,order_num) VALUES (3,3);
INSERT INTO test_order(item_id,order_num) VALUES (4,4);
INSERT INTO test_order(item_id,order_num) VALUES (5,5);
INSERT INTO test_order(item_id,order_num) VALUES (6,6);
INSERT INTO test_order(item_id,order_num) VALUES (7,7);
INSERT INTO test_order(item_id,order_num) VALUES (8,8);
INSERT INTO test_order(item_id,order_num) VALUES (9,9);
因为我们的日期是默认值是当前时间,所以要修改下时间
这里我故意没给设置八号的数据,稍后测试的时候再说
- Date()函数
我们的目标是计算过去几天的订单数量,简单测试,就过去四天好了
SELECT COUNT(1) as num,create_time FROM test_order GROUP BY create_time
但是,我们时间格式好像不对,这是就要用到Date()函数
SELECT COUNT(1) as num,DATE(create_time) as create_time FROM test_order GROUP BY create_time
这时候数据已经是我们想要的了
- 关联起来查询
SELECT
t1.currentdate,
t2.num
FROM
(
SELECT
curdate() AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 1 DAY ) AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 2 DAY ) AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 3 DAY ) AS currentdate
) AS t1
LEFT JOIN ( SELECT COUNT( 1 ) AS num, DATE( create_time ) AS create_time FROM test_order GROUP BY create_time ) t2 ON t1.currentdate = t2.create_time
这时候,我们想要的结果已经成形了,前面说到,我没给八号的设置数据,所以这里就是null了,但是这样不太好看,如果其中某一天没有数据,就设置成0
- IFNULL
SELECT
t1.currentdate,
IFNULL(t2.num,0) as num
FROM
(
SELECT
curdate() AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 1 DAY ) AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 2 DAY ) AS currentdate UNION ALL
SELECT
date_sub( curdate(), INTERVAL 3 DAY ) AS currentdate
) AS t1
LEFT JOIN ( SELECT COUNT( 1 ) AS num, DATE( create_time ) AS create_time FROM test_order GROUP BY create_time ) t2 ON t1.currentdate = t2.create_time
这就得到了我们想要效果
第二种思路
这一种思路是利用Java代码去实现的,也就是for循环去查询过去几天的数据,然后在合并。这是我刚学习Mysql的时候,用的一种方法。这里推荐一下Hutool工具
String today = DateUtil.today();
System.out.println("today = " + today);
如果是昨天,前天的日期改怎么获得呢?hutool的DateUtil里面同样也提供了方法
DateTime dateTime = DateUtil.offsetDay(new Date(), -1);
System.out.println("dateTime = " + dateTime);
第一个是日期,只需要把new一个Date放进去就行了,第二个参数是偏移量,正数就是未来时间,负数就是过去时间,1就代表一天,2就代表两天,以此类推。
但是,我们只需要年月日就需要在进行一次格式化
String date = DateUtil.formatDate(dateTime);
System.out.println("date = " + date);
剩下的就是过滤数据了,可以Java代码里面过滤,也可以for循环多调用几次数据库
如有错误,感谢指出!如有更好的方法,欢迎在评论区留言