背景:
数据质量做数据质检过程中,有一个这种业务场景,比如存在一张待办业务表,dbyw_sjb, 需要找出审核时间超过20(这个值可以动态变)个工作日的数据。
当时拿到这个需求,就在想怎么计算待办业务表提交时间,过20个工作日是什么时间,怎么计算??
需求难点:
1、每年的节假日都是动态的,数据库没有函数可以直接判断某个日期是否节假日
2、某个日期,比如1月3号,过10个工作日,到底是几号,到底怎么实现?
经过一段时间思考,想到方案如下
方案对比:
序号 | 方案 | 备注 |
1 | 把待办业务表(dbyw_sjb)数据查出来放到内存中,然后把提交时间+20天和审核时间进行对比 | 存在问题:1、如果业务表数据量大,把所有数据拉到内存,很可能爆内存, 2、计算多少个工作日后,不知道java有没有这种接口。 |
2 | 创建一张假期表,只保存节假日日期 | 要用存储过程,多数据源适配很麻烦(mysql、pg、达梦、hive、kingbase、orcale存储过程都不相同,很麻烦) |
3 | 创建一张日历表,标记某天是否是工作日 | 1、可以利用是否节假日,标记位以及limit实现这个功能 2、弊端:需要维护日历表,没维护的日期就没发计算,可以研究爬虫,爬万年历的数据,暂时没做。手动维护的日历表 |
方案实现
比较上面三种方案,选定的方案三
数据表 :办业务表dbyw_sjb(id,submit_time,udit_time,..........)
日历表 day_jq(id,rq_time,sfjjr,,,,,,,,,,)
日历表(day_jq)
字段 | 定义 | 备注 |
---|---|---|
id | id | |
日期 | rq_time | |
是否节假日 | sfjjr | |
星期几 | xqj | 为了以后如果有业务是跳过周末使用 |
其他字段 | ||
sfjjr是否节假日,submit_time 提交时间,udit_time审核时间
1、如果需要计算超过20个工作日处理的数据
select *
from dbyw_sjb a
where udit_time >= (select rq_time from day_jq
where sfjjr = 'N' and day_jq>= a.submit_time
order by day_jq asc limit 20)
or udit_time is null
这个方案,目前日历表数据是导入进去,新的一年还要维护这个表数据。后续考虑用爬虫自动拉数据进去,可以参考万年历节假日数据爬取-CSDN博客