要求:有两个列(时间格式),求出所有这两个列中的每一条的工作日总数(不含周六、不含周日,含开始时间,不含结束时间)先贴sql代码,一共五个算法(自测五个算法均无问题),其中第一种算法引用了一个function:
select t.created,
t.last_upd,
TO_CHAR(T.CREATED, 'D') 开始时间,
TO_CHAR(T.LAST_UPD, 'D') 结束时间,
cacl_workdays(t.created, t.last_upd) 第一种,
FLOOR((T.LAST_UPD - T.CREATED) / 7) * 5 + CASE
WHEN TO_CHAR(T.LAST_UPD, 'D') > TO_CHAR(T.CREATED, 'D') THEN --同一周(包含首天)
TO_CHAR(T.LAST_UPD, 'D') -
decode(TO_CHAR(T.CREATED, 'D'), 1, 2, TO_CHAR(T.CREATED, 'D'))
WHEN TO_CHAR(T.LAST_UPD, 'D')
TRUNC(t.last_upd - t.created) + 1 THEN --
0
ELSE
TRUNC((TRUNC(t.last_upd - t.created) -
(8 - TO_NUMBER(TO_CHAR(t.created, 'D')))) / 7) + 1
END) --周六
+ (CASE --
WHEN MOD(8 - TO_CHAR(t.created, 'D'), 7) >
TRUNC(t.last_upd - t.created) - 1 THEN
0
ELSE
TRUNC((TRUNC(t.last_upd - t.created) -
(MOD(8 - TO_CHAR(t.created, 'D'), 7) + 1)) / 7) + 1
END))) AS 第三种,
trunc((T.LAST_UPD - T.CREATED) / 7) * 5 +
nvl(length(replace(substr('01111100111110',
to_char(T.CREATED, 'd'),
mod(T.LAST_UPD - T.CREATED, 7)),
'0',
'')),
0) 第四种,
((TO_NUMBER(TRUNC(T.LAST_UPD, 'D') - TRUNC(T.CREATED + 6, 'D'))) / 7 * 5) + --隔板作用(中间段)
MOD(7 - TO_NUMBER(TO_CHAR(T.CREATED, 'D')), 6) + --前一段
greatest(TO_NUMBER(TO_CHAR(T.LAST_UPD, 'D')) - 2, 0) as 第五种 --后一段
from TEST1 t
复制代码再加一个functions的代码:
create or replace function cacl_workdays(statedate date,enddate date) return int is
Resultint ;
begin
select count(1)
into Result
from (select statedate + rownum-1 as dd
from dual
connect by rownum1
and to_char(t.dd,'d')7;
return(Result);
end cacl_workdays;
复制代码
|