Mysql查询时间段内数据,并处理相同日期或同类型的数据

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可以解决这个问题吗

猜你喜欢

转载自blog.csdn.net/xsj5211314/article/details/123164462