powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите отсчитать по календарю нужное число рабочих дней
3 сообщений из 3, страница 1 из 1
Помогите отсчитать по календарю нужное число рабочих дней
    #39977832
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть календарь в виде такой структуры:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE TABLE SCHEDULE_CALENDAR
(
  SCOPE        VARCHAR2(10 BYTE)                 NOT NULL,
  YYYY         NUMBER(4)            DEFAULT 0    NOT NULL,
  MM           NUMBER(2)            DEFAULT 0    NOT NULL,
  DD           NUMBER(2)            DEFAULT 0    NOT NULL,
  D            NUMBER(1)            DEFAULT 0    NOT NULL,
  CLASS        VARCHAR2(40 BYTE)                 NOT NULL,
  DESCRIPTION  VARCHAR2(200 BYTE)
)


Здесь 0 в числовых значениях означает глобальную маску, а любое другое значение задает соответствующий элемент даты (год, месяц, день, день недели), для которого действует запись.

Например производственный календарь на 2020 год выглядит таким образом:
SCOPEYYYYMMDDDCLASSDESCRIPTIONmain0000workПрофиль по умолчаниюmain0006freeВыходной (суббота)main0007freeВыходной (воскресенье)main0110freeНовогодние каникулыmain0120freeНовогодние каникулыmain0130freeНовогодние каникулыmain0140freeНовогодние каникулыmain0150freeНовогодние каникулыmain0160freeНовогодние каникулыmain0170freeРождество Христовоmain0180freeНовогодние каникулыmain02230freeДень защитника Отечестваmain0380freeМеждународный женский деньmain0510freeПраздник Весны и Трудаmain0590freeДень Победыmain06120freeДень Россииmain01140freeДень народного единстваmain20202240freeПеренос 23.02main2020390freeПеренос 08.03main2020540freeПеренос 04.01main2020550freeПеренос 05.01main20205110freeПеренос 09.05
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
with CAL as
(
select '' as SCOPE, 0 as YYYY, 0 as MM, 0 as DD, 0 as D, '' as CLASS, 'Профиль по умолчанию' as DESCRIPTION from DUAL where 0=1
union all select 'main', 0, 0, 0, 0, 'work', 'Профиль по умолчанию' from DUAL
union all select 'main', 0, 0, 0, 6, 'free', 'Выходной (суббота)' from DUAL
union all select 'main', 0, 0, 0, 7, 'free', 'Выходной (воскресенье)' from DUAL
union all select 'main', 0, 1, 1, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 2, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 3, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 4, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 5, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 6, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 1, 7, 0, 'free', 'Рождество Христово' from DUAL
union all select 'main', 0, 1, 8, 0, 'free', 'Новогодние каникулы' from DUAL
union all select 'main', 0, 2, 23, 0, 'free', 'День защитника Отечества' from DUAL
union all select 'main', 0, 3, 8, 0, 'free', 'Международный женский день' from DUAL
union all select 'main', 0, 5, 1, 0, 'free', 'Праздник Весны и Труда' from DUAL
union all select 'main', 0, 5, 9, 0, 'free', 'День Победы' from DUAL
union all select 'main', 0, 6, 12, 0, 'free', 'День России' from DUAL
union all select 'main', 0, 11, 4, 0, 'free', 'День народного единства' from DUAL
union all select 'main', 2020, 2, 24, 0, 'free', 'Перенос 23.02' from DUAL
union all select 'main', 2020, 3, 9, 0, 'free', 'Перенос 08.03' from DUAL
union all select 'main', 2020, 5, 4, 0, 'free', 'Перенос 04.01' from DUAL
union all select 'main', 2020, 5, 5, 0, 'free', 'Перенос 05.01' from DUAL
union all select 'main', 2020, 5, 11, 0, 'free', 'Перенос 09.05' from DUAL
)
select * from CAL


В CLASS задается класс дня (рабочий/нерабочий), в первой строке указывается значение класса по умолчанию, следующие две строки задают выходные дни, затем идут ежегодные праздники и наконец корректировочные записи для конкретного года.

Вот, например, календарь на текущий год:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
with CAL as (select trunc(sysdate,'Y')+ROWNUM-1 as DV from DUAL connect by level < (add_months(trunc(sysdate,'Y'),12)-trunc(sysdate,'Y')+1))
select SCOPE, CAL.DV as "DATE", MIN(CLASS) KEEP (DENSE_RANK FIRST ORDER BY decode(YYYY,0,365,0), decode(MM,0,30,0), decode(D,0,7,0), decode(DD,0,1,0)) as "CLASS"
, MIN(DESCRIPTION) KEEP (DENSE_RANK FIRST ORDER BY decode(YYYY,0,365,0), decode(MM,0,30,0), decode(D,0,7,0), decode(DD,0,1,0)) as "DESCRIPTION"
from CAL, SCHEDULE_CALENDAR
where SCOPE = 'main'
and (YYYY = 0 or to_number(to_char(CAL.DV,'YYYY')) = YYYY)
and (MM   = 0 or to_number(to_char(CAL.DV,'MM'))   = MM)
and (D    = 0 or 1+trunc(CAL.DV)-trunc(CAL.DV,'IW') = D)
and (DD   = 0 or to_number(to_char(CAL.DV,'DD'))   = DD)
group by SCOPE, CAL.DV
order by "SCOPE", "DATE"



Возникла задача, для которой мне нужно отсчитать от текущей даты плюс 3 рабочих дня (для которых CLASS='work').
Если делать в лоб, то можно просто сформировать календарь (аналогично предыдущему запросу) на +20 дней и уже по ним отсчитать 3 рабочих дня.
Но это как-то топорно. Мне кажется, что должен быть более прямой способ, основанный на аналитике и вычислениях. Но пока не соображу, откуда начать.
...
Рейтинг: 0 / 0
Помогите отсчитать по календарю нужное число рабочих дней
    #39977834
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.

Но это как-то топорно.

нетопорное еще ж и отрадить надо

луче сделайте ф-цию, которая бы определяла рабочий/выходной

по любому пригодится

ps
у Вас кажись на референдум выходных добавали, да и за вирус обещали

.....
stax
...
Рейтинг: 0 / 0
Помогите отсчитать по календарю нужное число рабочих дней
    #39977841
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax
да и за вирус обещали

Конституционный суд постановил, что "выходные, выходными не являются" ( C )
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите отсчитать по календарю нужное число рабочих дней
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]