热门关键词好会计 好业财 T+ 易代账 好生意 用友U8 用友BIP

    详细信息

    您现在的位置:网站首页 >> 百科问答 >> 详细信息

    Oracle 计算工时除去节假日 (精确到每天工作时间)

    特价活动:>>>> 畅云管家新购、续费8折优惠,畅捷通T+cloud、好会计、易代账、好业财、好生意云产品8折优惠 

    --可精确到每天的工作时间、全年法定休息日、节假日。结果返回小时数--前提条件:DIM_oa_TIME 包含每一天,并且is_work=1 工作日 =0 非工作日

    --首先创建工作时间视图createorreplaceviewVM_WORKTIMEas

    select1asid,'00:00:00'asbegintime,''||AM_WORK_BEGINTIME||':00'asendtime,0asworkhourfromWORKTIME_CURRENCY

    whereorg_account_id='67086964711'andweek_day_name=1andyearin(selectmax(year)yearfromWORKTIME_CURRENCYwhereorg_account_id='67086964711')

    unionall

    select2asid,''||AM_WORK_BEGINTIME||':00'asbegintime,''||AM_WORK_ENDTIME||':00'asendtime,3asworkhourfromWORKTIME_CURRENCY

    whereorg_account_id='67086964711'andweek_day_name=1andyearin(selectmax(year)yearfromWORKTIME_CURRENCYwhereorg_account_id='67086964711')

    unionall

    select3asid,''||AM_WORK_ENDTIME||':00'asbegintime,''||PM_WORK_BEGINTIME||':00'asendtime,0asworkhourfromWORKTIME_CURRENCY

    whereorg_account_id='67086964711'andweek_day_name=1andyearin(selectmax(year)yearfromWORKTIME_CURRENCYwhereorg_account_id='67086964711')

    unionall

    select4asid,''||PM_WORK_BEGINTIME||':00'asbegintime,''||PM_WORK_ENDTIME||':00'asendtime,4asworkhourfromWORKTIME_CURRENCY

    whereorg_account_id='67086964711'andweek_day_name=1andyearin(selectmax(year)yearfromWORKTIME_CURRENCYwhereorg_account_id='67086964711')

    unionallselect5asid,''||PM_WORK_ENDTIME||':00'asbegintime,'23:59:59'asendtime,0asworkhourfromWORKTIME_CURRENCY

    whereorg_account_id='67086964711'andweek_day_name=1andyearin(selectmax(year)yearfromWORKTIME_CURRENCYwhereorg_account_id='67086964711')



    结果为:



    -- 下面函数计算同一天内,两时间的工作时长 CREATEORREPLACEfunctiongetonedayworkhour(begintimeindate,endtimeindate)returnnumberas--一天内(工作日)从开始时间到结束时间的工作时长(返回值为多少天)v_begintime date; v_endtime date; v_nextdate date;--下一天0时v_date date;--当天0时beforeworkdaynumnumber(10,5);--开始时间与本区间(开始时间所在)结束时间相差时长endworkdaynumnumber(10,5);--结束时间所在区间的开始时间到结束时间相差时长workhournumnumber(10,5);--两时间相差几个时长workdaynumnumber(10,5);--两时间相差时长(天)id_order_befint;--记录开始时间VM_WORKTIME 区间号id_order_endint;--记录结束时间VM_WORKTIME 区间号beginv_begintime :=begintime;v_endtime :=endtime;v_nextdate :=To_date(To_char(v_begintime,'yyyy/mm/dd')||'23:59:59','yyyy/mm/dd hh24:mi:ss');--开始日期的23:59:59时--To_date(To_char(Trunc(v_begintime+1), 'yyyy/mm/dd hh24:mi:ss'), 'yyyy/mm/dd hh24:mi:ss')v_date :=To_date(To_char(Trunc(v_endtime),'yyyy/mm/dd hh24:mi:ss'),'yyyy/mm/dd hh24:mi:ss');--结束日期的当天0时beforeworkdaynum :=0;endworkdaynum :=0;workhournum :=0;ifv_begintimeisnullorv_endtimeisnullorv_begintime>v_endtime--开始时间大于结束时间thenworkhournum :=0;else--计算开始时间到本区间结束时间为多少时间(按天计算)selectidintoid_order_beffromVM_WORKTIMEwhereTo_date(To_char(v_begintime,'yyyy/mm/dd')||begintime,'yyyy/mm/dd hh24:mi:ss')<=v_begintimeandTo_date(To_char(v_begintime,'yyyy/mm/dd')||endtime,'yyyy/mm/dd hh24:mi:ss')>v_begintime;--开始日期在哪个时间区间ifid_order_bef<>2andid_order_bef<>4thenbeforeworkdaynum :=0;--select endtime into v_begintime from VM_WORKTIME where id=id_order_bef;--把本id_order_bef的endtime 作为v_begintime临时开始时间elseselectto_number(To_date(To_char(v_begintime,'yyyy/mm/dd')||endtime,'yyyy/mm/dd hh24:mi:ss')-v_begintime)--- v_begintime参数intobeforeworkdaynumfromVM_WORKTIMEwhereid=id_order_bef;--用本id_order_bef的endtime减v_begintime 计算本区间时间endif;--计算本区间开始时间到结束时间为多少时间(按天计算)selectidintoid_order_endfromVM_WORKTIMEwhereTo_date(To_char(v_endtime,'yyyy/mm/dd')||begintime,'yyyy/mm/dd hh24:mi:ss')=v_endtime;--结束日期在哪个时间区间ifid_order_end<>2andid_order_end<>4thenendworkdaynum :=0;--select endtime into v_endtime from VM_WORKTIME where id=id_order_end;--把本id_order_end的endtime 作为v_endtime临时开始时间elseselectto_number( v_endtime-To_date(To_char(v_endtime,'yyyy/mm/dd')||begintime,'yyyy/mm/dd hh24:mi:ss'))--- v_endtime参数intoendworkdaynumfromVM_WORKTIMEwhereid=id_order_end;--;--用本id_order_end的endtime减v_begintime 计算本区间时间endif;--计算开始时间到结束时间 中间有多少时间(按天计算)ifid_order_bef=id_order_endthenselectround(to_number( v_endtime-v_begintime),5)--- 在同一个区间 结束时间减开始时间intoworkdaynumfromdual;elseselectsum(nvl(workhour,0))/24intoworkdaynumfromVM_WORKTIMEwhereid>id_order_befandid


    --下面函数计算,两时间的工作时长CREATEORREPLACEfunctiongetworkhour(begindateindate,enddateindate)returnnumberas--两时间间隔多少小时(返回结果为小时)v_begindate date; v_enddate date; v_nextdate date;--下一天0时v_date date;--当天0时beforeworkhournumnumber(10,5);--开始时间育当天24点两时间相差几个小时endworkhournumnumber(10,5);--结束时间与当天0点两时间相差几个小时workhournumnumber(10,5);--两时间相差几个小时workdaynumnumber(10,5);--两时间相差几个整天工作日daynumnumber(10,5);--两时间相差几个整天is_workint;--是否为非工作日beginv_begindate :=begindate; v_enddate :=enddate; v_nextdate :=To_date(To_char(v_begindate,'yyyy/mm/dd')||'23:59:59','yyyy/mm/dd hh24:mi:ss');--开始日期的下一天0时v_date :=To_date(To_char(Trunc(v_enddate),'yyyy/mm/dd hh24:mi:ss'),'yyyy/mm/dd hh24:mi:ss');--结束日期的当天0时beforeworkhournum :=0; endworkhournum :=0; workhournum :=0; workdaynum :=0; daynum :=0;ifv_begindateisnullorv_enddateisnullorv_begindate>v_enddate--开始日期大于结束日期时thenworkhournum :=0;elseifto_number(To_date(To_char(v_begindate,'yyyy/mm/dd'),'yyyy/mm/dd hh24:mi:ss')-To_date(To_char(v_enddate,'yyyy/mm/dd'),'yyyy/mm/dd hh24:mi:ss'))=0--开始日期和结束日期时为同一天thenselectcount(*)intois_workfromDIM_oa_TIMEwherefdate=To_date(To_char(v_begindate,'yyyy/mm/dd'),'yyyy/mm/dd hh24:mi:ss')andis_work=1;--这天是否节假日ifis_work=0--or v_begindate is null or v_enddate is nullthenworkhournum :=0;elseworkhournum :=round(getonedayworkhour(v_begindate,v_enddate)*24,5) ;endif;elseselectcount(*)intois_workfromDIM_oa_TIMEwherefdate=To_date(To_char(v_begindate,'yyyy/mm/dd'),'yyyy/mm/dd hh24:mi:ss')andis_work=1;--开始日期是否节假日ifis_work=0--or v_begindate is nullthenbeforeworkhournum :=0;elsebeforeworkhournum :=round(getonedayworkhour(v_begindate,v_nextdate)*24,5)+beforeworkhournum;--开始时间到今天天最后一秒的小时数--select round(getonedayworkhour(to_date('2022-05-26 08:30:00','yyyy-mm-dd hh24:mi:ss'),To_date(To_char(to_date('2022-05-26 08:30:00','yyyy-mm-dd hh24:mi:ss'), 'yyyy/mm/dd')||' 23:59:59', 'yyyy/mm/dd hh24:mi:ss'))*24,5) from dual;endif;selectcount(*)intoworkdaynumfromDIM_oa_TIMEwherefdate>=v_begindateandfdate<=v_enddateandis_work=1;--工作日相差天数selectcount(*)intois_workfromDIM_oa_TIMEwherefdate=To_date(To_char(v_enddate,'yyyy/mm/dd'),'yyyy/mm/dd hh24:mi:ss')andis_work=1;--结束日期是否节假日ifis_work=0--or v_begindate is nullthen--如果v_enddate为节假日workdaynum不减1endworkhournum :=0;elseendworkhournum :=round(getonedayworkhour(v_date,v_enddate)*24,5)+endworkhournum;--下一天0时到结束时间的小时数workdaynum :=workdaynum-1;--如果v_enddate不为节假日workdaynum减1endif;--daynum :=to_date(To_char(v_enddate, 'yyyy/mm/dd'),'yyyy/mm/dd') - to_date(To_char(v_begindate, 'yyyy/mm/dd'),'yyyy/mm/dd'); --工作日相差天数endif;endif; workhournum :=nvl(workdaynum,0)*24+nvl(endworkhournum,0)+nvl(beforeworkhournum,0)+nvl(workhournum,0);returnworkhournum;end;---select getworkhour(to_date('2022-06-02 16:34:21','yyyy-mm-dd hh24:mi:ss'),to_date(' 2022-06-02 16:58:58','yyyy-mm-dd hh24:mi:ss')) from dual;--workhournum := round(getonedayworkhour(v_begindate,v_enddate)*24,5) ;--select (to_date(' 2022-06-02 16:58:58','yyyy-mm-dd hh24:mi:ss')-to_date('2022-06-02 16:34:21','yyyy-mm-dd hh24:mi:ss')) from dual;--select round(getonedayworkhour(to_date('2022-06-02 09:58:58','yyyy-mm-dd hh24:mi:ss'),to_date(' 2022-06-02 16:58:58','yyyy-mm-dd hh24:mi:ss'))*24,5) from dual;--select getonedayworkhour(to_date('2022-06-02 16:34:21','yyyy-mm-dd hh24:mi:ss'),to_date('2022-06-02 16:58:58','yyyy-mm-dd hh24:mi:ss'))*24 from dual;



     

     

    上一篇:Sql Server 数据库日志文件大的解决办法

    客服电话:400-665-0028

    关键字:用友财务软件,畅捷通软件,财务软件,进销存软件,U9官网,用友U8,用友T1,用友T+,用友T3,用友T6,畅捷通好会计,好生意,智+好业财,用友培训服务售后公司,畅捷通运营培训服务公司

    版权所有:用友畅捷通软件 Copyright © 2026 All rights reserved.

    鲁ICP备2020041017号-6