SQL > desc remove_red_days
Name Type Nullable Default Comments
-- -- ---- -------- ------- --------
DT DATE Y
SQL > select * from remove_red_days
2 /
DT
--------- --
27.02.2010
13.11.2010
SQL > desc add_red_days
Name Type Nullable Default Comments
-- -- ---- -------- ------- --------
DT DATE Y
SQL > select * from add_red_days
2 /
DT
--------- --
01.01.2010
04.01.2010
05.01.2010
06.01.2010
07.01.2010
08.01.2010
22.02.2010
23.02.2010
08.03.2010
03.05.2010
10.05.2010
14.06.2010
04.11.2010
05.11.2010
14 rows selected
SQL > desc cb_reports_settings
Name Type Nullable Default Comments
------------- -- ------------- -------- ------- --------
FORM_NAME VARCHAR2(100) Y
CALENDAR_DAY NUMBER(2) Y
WORKING_DAY NUMBER(2) Y
TIME_TO_BE_SENT NUMBER(2) Y
IS_QUARTERLY NUMBER(1) Y
SQL > select * from cb_reports_settings
2 /
FORM_NAME CALENDAR_DAY WORKING_DAY TIME_TO_BE_SENT IS_QUARTERLY
------------------- -- ------------ ----------- --------------- ------------
350 1 2 0
301 1 2 13 0
634_ 1 4 0
101 1 4 0
134 1 4 0
135 1 6 0
153 1 6 0
711 1 5 0
301 5 2 13 0
115 1 7 0
116 1 7 0
117 1 7 0
118 1 7 0
155 1 7 0
125 1 8 0
157 1 8 0
501 1 8 0
603 1 8 0
102 1 8 1
110 1 8 0
128 1 7 0
129 1 7 0
302 1 10 0
316 1 10 0
251 1 10 1
401 1 10 0
301 10 2 13 0
350 11 2 0
634_ 11 4 0
345 1 11 1
405 1 17 0
301 15 2 13 0
301 20 2 13 0
350 21 2 0
634_ 21 4 0
301 25 2 13 0
342- () 1 10 0
37 rows selected
* This source code was highlighted with Source Code Highlighter .
/* */
with t1 as ( select trunc(sysdate, 'y' )+rownum-1 dt from dual connect by level <=365),
--
/* */
t2 as ( select dt, row_number() over (partition by trunc(dt, 'mm' ) order by dt) working_day,
row_number() over ( order by dt) wd2 from t1
where (mod(to_char(dt, 'j' ),7) +1 not in (6,7)--
or dt in ( select dt from remove_red_days)) -- ,
and dt not in ( select dt from add_red_days)), --
--
/* */
t3 as ( select t1.dt, to_number(to_char(t1.dt, 'dd' )) calendar_day, working_day, wd2 from t1, t2
where t1.dt = t2.dt(+)
order by t1.dt),
--
/* , , */
t4 as (
select t3.*,
first_value(decode(working_day, null , null , t3.wd2) ignore nulls) over ( order by t3.dt rows between current row and unbounded following) wd3,
first_value(decode(working_day, null , null , t3.dt) ignore nulls) over ( order by t3.dt rows between current row and unbounded following) dt2,
nvl2(working_day, dt, null ) dt3
from t3
) /* select * from t4*/,
--
t5 as ( select ( select dt
from t4 t4_inner
where t4_inner.wd3 - t4_outer.wd3 + 1 = cbrs.working_day
and t4_inner.wd2 is not null
and rownum = 1) needed_date,
t4_outer.*,
cbrs.*
from t4 t4_outer,
cb_reports_settings cbrs
where t4_outer.calendar_day = cbrs.calendar_day
and (cbrs.is_quarterly = 0 or cbrs.is_quarterly = 1 and trunc(t4_outer.dt, 'mm' ) = trunc(t4_outer.dt, 'Q' ))
order by 1)
--
select '"' ||form_name|| '","' ||to_char(needed_date, 'dd.mm.yyyy' )|| '","' ||nvl(time_to_be_sent, '17' )|| ':00:00","' ||to_char(needed_date, 'dd.mm.yyyy' )|| '","' ||nvl(time_to_be_sent, '17' )|| ':00:00","","","' ||to_char(needed_date, 'dd.mm.yyyy' )|| '","09:00:00",""' col
from t5
order by form_name, needed_date
* This source code was highlighted with Source Code Highlighter .
COL
--------
"101","14.01.2010","17:00:00","14.01.2010","17:00:00","","","14.01.2010","09:00:00",""
"101","04.02.2010","17:00:00","04.02.2010","17:00:00","","","04.02.2010","09:00:00",""
"101","04.03.2010","17:00:00","04.03.2010","17:00:00","","","04.03.2010","09:00:00",""
"101","06.04.2010","17:00:00","06.04.2010","17:00:00","","","06.04.2010","09:00:00",""
"101","07.05.2010","17:00:00","07.05.2010","17:00:00","","","07.05.2010","09:00:00",""
"101","04.06.2010","17:00:00","04.06.2010","17:00:00","","","04.06.2010","09:00:00",""
"101","06.07.2010","17:00:00","06.07.2010","17:00:00","","","06.07.2010","09:00:00",""
"101","05.08.2010","17:00:00","05.08.2010","17:00:00","","","05.08.2010","09:00:00",""
"101","06.09.2010","17:00:00","06.09.2010","17:00:00","","","06.09.2010","09:00:00",""
"101","06.10.2010","17:00:00","06.10.2010","17:00:00","","","06.10.2010","09:00:00",""
...
Source: https://habr.com/ru/post/96496/