Mysql查询时间段内数据
表如图,表名为demo,表为某库存量的实时更新表
主要数据为:time时间数据,amount库存量数据
Mysql查询时间段内的数据可以用between方法
select amount
from demo
where time
between "2021-01-01 00:00:00" and "2022-01-01 00:00:00"
要注意的是between右边的数据如果相同,并不会统计在内,即开括号
如果需要的数据只精确到天,且参数无时分秒,会造成时间段末端数据丢失,即1月1号的数据并不会计算在内
可以用java的Calender进行扩大范围
Calendar gc = Calendar.getInstance();
Date a=productionParam.getEndtime();
gc.setTime(a);
gc.add(Calendar.DAY_OF_MONTH, 1 );
gc.add(Calendar.SECOND,-1);
将末端数据加一天,减1秒,即为“2022-01-01 23:59:59”,可以将1月1号的数据统计在内
对相同日期的数据进行处理
可以看出,第三条和第四条的日期(精确到天)是相同
处理可以分为两种情况,相加或选择其中一个
相加可以用sql的sum()函数和group by
需要注意的是,由于两条数据时分秒不同,group by不能直接分组,可以用mysql的DATE_FORMAT进行格式处理后,再进行分组,由于格式化和分组不能同时,所以需要二次查询
select
time,sum(amount)
from(
select
DATE_FORMAT(time, '%Y-%m-%d' ) AS time,
amount
from demo) as a
group by
a.time
相同日期选择其中一个
假设相同日期的数据只需要最新的那一条数据,可以使用mysql的MAX()方法
同样的,日期也需要格式化,并分组,但分组后amount的数据并不可控,而且最重要的是日期格式化后并不能分清,相同日期的数据中哪一条是最新的,即精确度丢失
所以需要用到 id字段,默认日期是按顺序插入的,即id也是按顺序排列,此时可以用左连接Right join实现该需求
select
id,
time,
amount
from demo
RIGHT JOIN (
select
MAX(id) as id
from(
select
id,
DATE_FORMAT(time, '%Y-%m-%d' ) AS time,
amount
from demo) as a
group by
a.time ) as b
on id=b.id
再然后,在生产中
需求改变,需要反应时间段内的每一天库存量总和,用于统计或折线图
需要根据type类型的数据再次分类,且需要查询每一天的所有种类的库存量之和,
最重要的是有时间段的划分,但时间段之外的数据依然需要考虑(所有种类库存量的和),而且需要一个在时间段开始前的库存量初始值(折线图起点)
可以理解为
查询某一时间段的库存量,即amount,需要查询在时间段内的每一天的库存量总和,当天库存量总和为当天所有种类(type)的库存量的和,数据库的每一条数据为一种类的库存量的实时更新数据。
查询时,同一种类的数据在同一天出现时选取最新的数据,且,当查询出的库存量总和不在时间段的前端时,需要查询初始值,即时间段前的库存量总和,也就是当任何一种类的库存量不在时间段的前端时,需要查询时间段前的初始值并用于后续的库存量总和计算
这个时候,光用数据库查询,已经满足不了需求
我的解决方法是
查询出生产资料的所有type类型编号,逐个查询时间段前的类型初始值放在数组中,然后group by两个字段(time和type)分组,得到不同种类实时变化的数据,剔除同一种类在同一天变化的数据,最后根据查询出的日期,类型和库存量,不断替换数组内库存量值,进行计算
如果只用sql可以解决这个问题吗