我创建了函数以获取最近5个工作日。它将显示该计划的当月的最后一个第5天。
我创建了一个包含假期列表的表。你能帮我修改一下这个功能吗?我尝试了如下函数,
查询后插入
AND NOT EXISTS (SELECT 1 FROM T_FACT_JOB_HOLIDAY_LIST WHERE HDLY_DATE = end_date)
主要查询:
CREATE OR replace FUNCTION test.Func_to_get_last_n_busi_days (
p_curr_date IN DATE,
p_days_cnt IN NUMBER)
RETURN DATE
IS
v_curr_date DATE := Trunc(p_curr_date);
v_days_cnt NUMBER := p_days_cnt;
v_month_end_date DATE;
v_sche_date DATE;
BEGIN
v_month_end_date := Last_day(v_curr_date);
IF v_month_end_date = v_curr_date THEN
v_month_end_date := Last_day(v_curr_date + 1);
END IF;
SELECT Min(last_n_days)
INTO v_sche_date
FROM (SELECT last_n_days
FROM (SELECT ROWNUM rw,
end_date - LEVEL + 1 last_n_days
FROM (SELECT Add_months(( v_month_end_date + 1 ), -1) AS
start_date,
v_month_end_date AS
end_date
FROM dual)
WHERE To_char(end_date - LEVEL + 1, 'DY') NOT IN
( 'SAT', 'SUN' )
CONNECT BY LEVEL <= ( end_date - start_date ) + 1)
WHERE rw <= v_days_cnt)
WHERE last_n_days > v_curr_date;
RETURN Trunc(v_sche_date);
EXCEPTION
WHEN OTHERS THEN
Raise_application_error(-20010, SQLERRM);
END;
/
答案 0 :(得分:1)
你可以像这样生成v_month_end_date到v_curr_date的日期列表:
select v_month_end_date - level + 1 as d
from dual
connect by v_month_end_date - v_curr_date >= level -1
然后您可以按照以下方式过滤工作日和假日的日期:
select d
from
(
select v_month_end_date - level + 1 as d
from dual
connect by v_month_end_date - v_curr_date >= level -1
)
where To_char(d, 'DY', 'NLS_DATE_LANGUAGE = american') NOT IN ( 'SAT', 'SUN' )
and NOT EXISTS (SELECT 1 FROM T_FACT_JOB_HOLIDAY_LIST WHERE HDLY_DATE = d)
order by d desc
在下一步中,您只过滤所需的商务天数并选择最短日期
select min(d)
into v_sche_date
FROM
(
SELECT d
from
(
select rownum rn, d
from
(
select d
from
(
select v_month_end_date - level + 1 as d
from dual
connect by v_month_end_date - v_curr_date >= level -1
)
where To_char(d, 'DY', 'NLS_DATE_LANGUAGE = american') NOT IN ( 'SAT', 'SUN' )
and NOT EXISTS (SELECT 1 FROM T_FACT_JOB_HOLIDAY_LIST WHERE TRUNC(HDLY_DATE, 'DD') = d)
order by d desc
)
)
where
rn <= v_days_cnt
)
答案 1 :(得分:0)
你试过了:
... AND NOT EXISTS (SELECT 1 FROM T_FACT_JOB_HOLIDAY_LIST
WHERE HDLY_DATE = end_date)
你应该尝试(第28行):
... AND NOT EXISTS (SELECT 1 FROM T_FACT_JOB_HOLIDAY_LIST
WHERE HDLY_DATE = end_date - LEVEL + 1)
但也许这个功能有点难以理解。你也可以做这个简单的循环:
create or replace function get_business_day (p_curr_date in date, p_days_cnt in number )
return date is
v_date date := last_day(p_curr_date);
i number := 0;
v_tmp number;
begin
while i < p_days_cnt loop
v_date := v_date - 1;
begin
select 1 into v_tmp from t_fact_job_holiday_list where hdly_date = v_date;
exception when no_data_found then
i := i + 1;
end;
end loop;
return v_date;
end;