跳过多少个工作日sql实现

博客围绕数据质检中找出审核时间超20个工作日数据的需求展开。需求难点在于动态节假日判断及工作日计算。经思考给出方案,选定方案三,包含计算超20个工作日处理数据的SQL、节假日表初始化数据SQL,还提供查询节假日的openAPi,可用于改造初始化方法和定时更新数据。

目录

1需求描述

2方案对比

3方案实现

3.1、如果需要计算超过20个工作日处理的数据sql

3.2、节假日表初始化数据sql

3.3 查询节假日的openAPi



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)

字段

定义

备注

idid
日期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的初始化方法,并且增加定时任务,每年年初初始化节假日表的数据。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哓炎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值