Oracle 计算起始日期之间的工作日天数(目前只支持同一年)
需求
计算2020.4.13号到2020.8.6号之间总共多少个工作日(去除周末和节假日)。
解决办法
人工解决方法:
用手机看着日历数天数累加,哈哈
自动计算方法:
SQL自动计算
如下是计算函数:
create or replace function count_workdays(startdate date,enddate date,is_clude_weekend int --是否包括特殊日期-周末的工作日 0|不包括,1|包括
) return varchar2
isc_year int; --计算的年份s_month int; --开始月份e_month int; --结束月份s_day int; --开始的天数e_day int; --结束的天数l_day date; --某月的最后一天c_f_day date; --某月开始计算的第一天diff_day int; --相差天数ct_total int := 0; --计算出的总天数ct_workday int := 0; --计算出的工作日天数(不包括周末、节假日)str_info varchar2(32767); --范围内的工作日拼接str_month varchar2(10000); --范围内的月份拼接is_holiday int; --是否是节假日 is_spec_workday int; --是否为特殊工作日(周末的工作日)i_holiday int; --临时接收节假日变量 i_spec_workday int; --临时接收特殊工作日变量str_holiday varchar2(10000); --范围内的节假日拼接
begin--将月份、天数赋值到临时变量s_month := extract(month from startdate);s_day := extract(day from startdate);e_month := extract(month from enddate);e_day := extract(day from enddate);--判断日期是否顺序错误if startdate > enddate thenreturn '开始日期不允许大于结束日期';end if;--暂时不考虑跨年的情况if extract(year from startdate) != extract(year from enddate) thenreturn '目前暂不支持跨年计算';elsec_year := extract(year from startdate);end if; --循环每个月FOR m in 0..(e_month - s_month) LOOP str_month := str_month ||'【'|| (s_month + m)|| '】 ';--dbms_output.put_line('当前月份 = '||(s_month + m));select last_day(to_date(c_year||lpad(s_month + m,2,0)||'01','yyyymmdd')) into l_day from dual;--根据当月不同,计算不同的相差天数值if s_month < e_month then select case when m = 0 thenl_day - startdate --开始日期所在月份最后一天 - 开始日期when s_month + m = e_month thenenddate - (add_months(last_day(enddate),-1) + 1) --结束日期 - 结束日期所在月份第一天elsel_day - (add_months(l_day,-1) + 1) --该月最后一天 - 该月第一天end ,--相差天数case when m = 0 thenstartdate --开始日期所在月份的第一天when s_month + m = e_month thenadd_months(last_day(enddate),-1) + 1 --结束日期所在月份的第一天elseadd_months(l_day,-1) + 1 --该月份第一天 end --该月份第一天 into diff_day , c_f_dayfrom dual; elseselect e_day - s_day,startdate into diff_day,c_f_day from dual;end if;--dbms_output.put_line('当前月份相差天数 = '||diff_day);if s_month + m = e_month then dbms_output.put_line('当前月份起始日期 = '||to_char(enddate,'yyyymmdd') ||' - '||to_char(add_months(last_day(enddate),-1) + 1,'yyyymmdd') || ' |开始计算日期 = '||to_char(c_f_day,'yyyymmdd') );end if;--dbms_output.put_line('当前月份开始计算日期 = '||c_f_day);--循环每天for d in 0..diff_day loop--先判断的该日期是否为节假日select count(1),max(s_date) into is_holiday,i_holiday from JS_JJRJLB where s_type = 3 and s_date = to_number(to_char((c_f_day + d),'yyyymmdd')); if is_holiday = 0 then if to_char((c_f_day + d),'D') not in('1','7') then --不是周末ct_workday := ct_workday + 1 ;str_info := str_info||'| '||to_char((c_f_day + d),'yyyymmdd'); elsif(is_clude_weekend = 1) then --是周末且需要计算周末中的工作日--取出周末的工作日(在特殊日期表中查询)select count(1),max(s_date) into is_spec_workday,i_spec_workday from JS_JJRJLB where s_type = 1 and s_date = to_number(to_char((c_f_day + d),'yyyymmdd')); if is_spec_workday > 0 then ct_workday := ct_workday + 1 ;str_info := str_info||'| '||i_spec_workday; end if; end if;else--拼接范围内的节假日str_holiday := str_holiday||'- '||i_holiday ;end if; ct_total := ct_total + 1; end loop;END LOOP;return '[total_days] = '||ct_total||' [workdays] = '||ct_workday ||' [符合要求的日期] = '||substr(str_info,2)||' [节假日] = '||substr(str_holiday,2);
end count_workdays;
排除节假日创建的-特殊日期表
create table JS_JJRJLB
(id NUMBER(16) not null,s_date NUMBER(8),s_type NUMBER(12) --1|工作日 2|周末 3|节假日
)
测试验证
select count_workdays(to_date('20200413','yyyy-mm-dd'),to_date('20200806','yyyymmdd'),0) from dual;
查询结果如下:
后续会添加跨年计算的功能 ...
因为第一次写这种函数,可能有些地方逻辑写复杂了,希望有简便方法的前辈们不吝赐教,也欢迎发现问题的小伙伴在留言区留言,一起讨论学习,共同进步(找不到功能栏里面的小猴子表情了,就用符号代替啦 ^_^)
Oracle 计算起始日期之间的工作日天数(目前只支持同一年)相关推荐
- oracle 节假日天数,强大的PLSQL - 计算两个日期之间的工作日天数-除去(周末和公共假日...
用php写了一个函数,实现的功能是 计算两个日期之间的工作日天数-除去(周末和公共假日)写了 300多行的代码, 实现公共假日从文件中读取, 或者从数据库提取, 然后传入两个日期,就能返回想要的结果 ...
- SQL计算两个日期之间的工作日天数,去除法定节假日和周末
项目要求:需要计算两个日期之间的工作日天数,包含元旦.五一.十一等法定假日. 网上查询很多SQL函数,最终发现都不太理想,例如国庆放假可能会调休,周末也要上班.所以唯一的解决方案是建立一张工作日时间表 ...
- oracle计算一个日期加上指定工作日(排除周六周日和一系列节假日)时间
第一步: 创建一个表格holiday用于灵活存放节假日日期(周末除外),如果和周末日期重复,则无需添加到该表格中: create table T_RENT_HOLIDAY ( ID VARCHAR2( ...
- 计算两个日期之间的工作日天数
计算两个工作日之间的天数 : 利用循环遍历开始时间和结束时间之间的天数,工作日则累计,非工作日跳过,不过如果开始时间和结束时间之间很长,效率可能不高, import java.text.DateFor ...
- SQL计算两个日期之间的工作日天数
https://blog.csdn.net/qq_37436998/article/details/85867729 参考这篇文章,先创建数据库,然后通过插入数据库一个函数,这样写SQL的时候就调用这 ...
- mysql 计算两个日期之间的工作日天数
2019独角兽企业重金招聘Python工程师标准>>> 创建透视表t500 建表 CREATE TABLE `t500` (`id` int(11) NOT NULL AUTO_IN ...
- 【excel】利用NETWORKDAYS.INTL函数计算两日期之间的工作日时间
语法 NETWORKDAYS.INTL(start_date, end_date, [weekend], [holidays]) start_date 和 end_date:必需,要计算其差值的日期. ...
- Java获取两个日期之间的工作日天数
参数:开始日期,结束日期 String 返回值:天数 int @SuppressWarnings("deprecation") public int getDutyDays(Str ...
- oracle计算每月最小工作日,Oracle计算指定日期内的工作日(不包含周末)
1.获取当天是礼拜几:select to_char(sysdate,'d') from dual; --礼拜天为1,礼拜一为2,类推 2.获取 两个时间段间的 工作日: select (trunc(& ...
- oracle取某年工作日,Oracle计算指定日期内的工作日(不包含周末)
1.获取当天是礼拜几:select to_char(sysdate,'d') from dual; --礼拜天为1,礼拜一为2,类推 2.获取 两个时间段间的 工作日: select (trunc(& ...
最新文章
- Entity Framework快速入门笔记第四篇—ModelFirst
- CentOS中怎样安装、配置、启动Nginx
- 传入一个中文字符串,返回一个字符串中的中文拼音
- 在有限多的不大于100的正整数中,找出尽量多个相加起来值介于98~102之间的组合...
- VIP - virtual IP address
- C++ const关键字总结
- mysql 与gemfire的同步_(转)分布式缓存GemFire架构介绍
- 2021年上半年内容型社交电商行业分析报告
- html中li标签之间有缝隙,liimg标签之间空隙bug
- DSSM算法-计算文本相似度
- 剑指 Offer II 044. 二叉树每层的最大值
- 手机怎么用外嵌字幕_怎么用手机给视频添加字幕?原来方法这么简单,3分钟教你学会...
- 博弈论:零和博弈与常和博弈的区别
- 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付
- “竹影扫阶尘不动,月穿潭底水无痕”引出的……
- 【镀金与沉金工艺的区别,今后得选“沉金”】
- TEA XTEA XXTEA
- 世界有时特别吝啬【摘自《青年文摘》】
- 微信小程序:Do not set same key \5cef8733d2a18eed506c1165\ in wx:key.
- flash flash页面的的全屏展示
热门文章
- 论文:A Real-Time Cross-modality Correlation Filtering Method for Referring Expression Comprehension
- 运动控制 轨迹规划综述
- delphi去掉字段前后的引号_delphi 单引号在字符串中使用方法
- 陆奇如何解构一家企业?
- 职场五大能力之学习能力
- 非同帆响-得帆信息发布全新高生产力PaaS平台,重新定义企业软件生产力
- 编译原理:cminus_compiler-2021-fall Lab3
- PS-sixday-裁剪和切片(标尺使用)
- ubuntu18.04 安装Teamviewer15出现依赖库出错的解决办法
- [gitlab] 解决:remote: Ask a project Owner or Maintainer to create a default branch: