最近项目中有个业务是查询年月区间的,年和月是两个字段。
(1)表结构
其中statistic_year是int类型的,statistic_month是varchar类型的
(2)前端传参
约定固定4个值。意思是,查询日期区间为2019年01月~2020年09月的数据(可能会有其他参数限定)
(3)后端接收
List<Integer> year;
List<String> month;
(4)解决方法
百度了亿下,虽然没找到正好合适的代码,但看到网上大部分思路都是拼接,以下是尝试的方法。
cast(value as type);
convert(value as type);
- 年+月
select
statistic_hour as hour,
SUM(case when jcflag=0 then COALESCE(cnt,0) else 0 end) as inCnt,
SUM(case when jcflag=1 then COALESCE(cnt,0) else 0 end) as outCnt
from gd_rail_station_flow
where concat(cast(statistic_year as VARCHAR(10)),'-',statistic_month) BETWEEN '2019-08' and '2020-12'
GROUP BY statistic_hour ORDER BY statistic_hour
先用cast函数将statistic_year转成varchar(10),这里需要带上字符的长度,不然会报错。然后再用concat将各个字符连接起来。就成了2020-09形式。后端传的时候需要拼接下year和month
结果:
- 年+月+‘01 00:00.000’
select
statistic_hour as hour,
SUM(case when jcflag=0 then COALESCE(cnt,0) else 0 end) as inCnt,
SUM(case when jcflag=1 then COALESCE(cnt,0) else 0 end) as outCnt
from gd_rail_station_flow
where CONVERT(concat(cast(statistic_year as VARCHAR(10)),'-',statistic_month,'-01 00:00:00.000'),datetime) BETWEEN '2019-08-01 00:00:00' and '2020-01-01 00:00:00'
GROUP BY statistic_hour ORDER BY statistic_hour
如果是年+月+‘01 00:00.000’的形式,就是需要转成datetime类型,形如’2020-12-01 00:00:00’。between和and里的也需要通过后端拼接转换成datetime类型。
结果:
随后又比较了两种方法,所用的查询时间差不多。
目前数据量是166w多条。
但如果是大数据量的话,查询效率应该不高…后续优化吧。
╮(╯▽╰)╭
(5)测试
最后通过前后端测试一下吧,以防出现bug。
比如查询数据库中这几条记录:
2020-10~2021-07,就前三条数据。
前端传参:
后端部分:
结果: