目录
1需求描述
数据质量做数据质检过程中,有一个这种业务场景,比如存在一张待办业务表,dbyw_sjb, 需要找出审核时间超过20(这个值可以动态变)个工作日的数据。
当时拿到这个需求,就在想怎么计算待办业务表提交时间,过20个工作日是什么时间,怎么计算??
需求难点:
1、每年的节假日都是动态的,数据库没有函数可以直接判断某个日期是否节假日
2、某个日期,比如1月3号,过10个工作日,到底是几号,到底怎么实现?
经过一段时间思考,想到方案如下
2方案对比
| 序号 | 方案 | 备注 |
| 1 | 把待办业务表(dbyw_sjb)数据查出来放到内存中,然后把提交时间+20天和审核时间进行对比 | 存在问题:1、如果业务表数据量大,把所有数据拉到内存,很可能爆内存, 2、计算多少个工作日后,不知道java有没有这种接口。 |
| 2 | 创建一张假期表,只保存节假日日期 | 要用存储过程,多数据源适配很麻烦(mysql、pg、达梦、hive、kingbase、orcale存储过程都不相同,很麻烦) |
| 3 | 创建一张日历表,标记某天是否是工作日 | 1、可以利用是否节假日,标记位以及limit实现这个功能 2、弊端:需要维护日历表,没维护的日期就没发计算,可以研究爬虫,爬万年历的数据,暂时没做。手动维护的日历表 |
3方案实现
比较上面三种方案,选定的方案三
数据表 :办业务表dbyw_sjb(id,submit_time,udit_time,..........)
节假日表week_day(id,rq,sfjjr,,,,,,,,,,)
日历表(day_jq)
| 字段 | 定义 | 备注 |
|---|---|---|
| id | id | |
| 日期 | rq | |
| 是否节假日 | sfjjr | |
sfjjr是否节假日,submit_time 提交时间,udit_time审核时间
3.1、如果需要计算超过20个工作日处理的数据sql
select *
from dbyw_sjb a
where udit_time >= (select rq from weekday
where sfjjr = 'N' and rq>= a.submit_time
order by rq asc limit 20)
or udit_time is null
3.2、节假日表初始化数据sql
周六、周日默认节假日、国家法定节假日默认节假日。 调休的不管,需要每年个性化调整
public void initWeekDaySj(int year) {
String bywm = Constants.ZL_WEEKDAY;
String dayYear = year+"-01-01";
//判断数据是不是存在
String sql1 = " select count(1) from " + bywm +" where rq='"+dayYear+"'";
Long count = zlJdbcUtil.queryCount(sql1);
if(count!=null && count!=0){
return;
}
int daysInYear = Year.of(year).length();
//全年日期
String sql = " insert into " + bywm + "(rq,sfjjr) values";
for (int i = 1; i <= daysInYear; i++) {
LocalDate date = LocalDate.ofYearDay(year, i);
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String day = date.format(df);
//默认的国家法定节假日
List<String> mrJjrList = Arrays.asList("01-01", "04-05", "05-01", "05-02", "05-03",
"10-01", "10-02", "10-03", "10-04", "10-05", "10-06", "10-07");
String rq = day.substring(5);
//周六、周日默认节假日
if (DayOfWeek.SATURDAY.equals(date.getDayOfWeek()) || DayOfWeek.SUNDAY.equals(date.getDayOfWeek())
|| mrJjrList.contains(rq)) {
sql += "('" + day + "','Y'),";
} else {
sql += "('" + day + "','N'),";
}
}
sql = sql.substring(0, sql.length() - 1) + ";";
//执行sql语句
}
3.3 查询节假日的openAPi
查询节假日的api,url地址如下:
https://oneapi.coderbox.cn/openapi/public/holiday?date=2018&queryType=2
API地址:https://oneapi.coderbox.cn/openapi/public/holiday
文档地址:https://oneapi.coderbox.cn/doc/949712861251586
参数:date, 传年
参数:queryType : 1只查节假日, 2查一年的所有天
可以通过这个接口,改造3.2的初始化方法,并且增加定时任务,每年年初初始化节假日表的数据。
博客围绕数据质检中找出审核时间超20个工作日数据的需求展开。需求难点在于动态节假日判断及工作日计算。经思考给出方案,选定方案三,包含计算超20个工作日处理数据的SQL、节假日表初始化数据SQL,还提供查询节假日的openAPi,可用于改造初始化方法和定时更新数据。

1万+

被折叠的 条评论
为什么被折叠?



