Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 конец квартала (исключая выходные дни)  [new]
ecivgamer
Member

Откуда:
Сообщений: 692
Привет всем,
вот моя попытка вычислить конец квартала (исключая выходные дни) :

with 
 
calendar1 as
(select * from 
(select to_date('29.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
 select to_date('30.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
 select to_date('31.03.2012','DD.MM.YYYY') as arcdate, 1 as dayoff from dual)
 where dayoff = 0), 
 
end1 as
(select TRUNC(ADD_MONTHS(to_date('25.03.2012','DD.MM.YYYY'), +1), 'Q')-1 as end_of_quarter from dual) 
 
select max(calendar1.arcdate) as end_of_quarter 
from calendar1, end1 
where calendar1.arcdate <= end1.end_of_quarter

Ищу способ создать динамически список окончаний кварталов (без выходных) с начала 2010 по конец 2012 года, причем выходной - это не только суббота и воскресенье, но и государственные праздники (на реальной базе - таблица calendar).

Подскажите решение, пожалуйста.
14 июл 11, 12:38    [10972791]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
- вычислить последний день квартала
- найти ближайший предыдущий рабочий день.

Какой пункт вызывает затруднение?
14 июл 11, 12:44    [10972869]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
ecivgamer
Member

Откуда:
Сообщений: 692
AlexFF__|,

учусь пользоваться собственными мозгами.... (((((

Для _одного_ квартала все понятно. Непонятно, как сделать динамически для каждого квартала за период с начала 2010 по конец 2012 года.
14 июл 11, 12:47    [10972896]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
Vint
Member

Откуда: Москва
Сообщений: 4564
и в чем проблема?
взять все даты за период. поставить кадой квартал
выкинуть все выходные.
взять максимальную дату в каждом квартале

или

взять последнюю дату в кадом квартале и 2 предыдущие. за весь период
выкинуть выходные.
взять максимальную для кадого квартала

еще придумывать варианты лень.
14 июл 11, 12:57    [10973018]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
ecivgamer
Member

Откуда:
Сообщений: 692
Vint
взять все даты за период. поставить кадой квартал
выкинуть все выходные.
взять максимальную дату в каждом квартале


подскажите пример кода плз.
14 июл 11, 13:00    [10973043]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
ecivgamer
Vint
взять все даты за период. поставить кадой квартал
выкинуть все выходные.
взять максимальную дату в каждом квартале


подскажите пример кода плз.


Неужели так тяжело?
with days as ( select date '2010-01-01' + level - 1 dt, least(mod(level, 7),1) h from dual connect by level < 1090 )
select max( decode(h,1,dt) ) from days
    group by trunc( dt, 'Q' )
    order by trunc( dt, 'Q' );
14 июл 11, 13:21    [10973266]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
bev
Member

Откуда: СПб
Сообщений: 143
AlexFF__|
к сожалению, ответ не соответствует календарю...
14 июл 11, 13:37    [10973400]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
bev
AlexFF__|
к сожалению, ответ не соответствует календарю...

К сожалению, я лишь могу дать ответ, но не могу научить людей пользоваться мозгами.
14 июл 11, 13:41    [10973448]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
ecivgamer
Member

Откуда:
Сообщений: 692
Вот решение (к сожалению, дошел не своими мозгами, а получил ответ на другом форуме) :

with calendar1 as (select * 
                   from   (select to_date('29.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
                           select to_date('30.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
                           select to_date('31.03.2012','DD.MM.YYYY') as arcdate, 1 as dayoff from dual)
                   where dayoff = 0), 
          end1 as (select TRUNC(ADD_MONTHS(sysdate, (level - 8)*3), 'Q') start_of_quarter,
                          ADD_MONTHS(TRUNC(ADD_MONTHS(sysdate, (level - 8)*3), 'Q'), +3)-1 as end_of_quarter 
                   from dual
                   connect by level <= 16) 
select e1.start_of_quarter, nvl(max(c1.arcdate), e1.end_of_quarter) as actual_end_of_quarter 
from   calendar1 c1, 
       end1 e1
where  c1.arcdate(+) between e1.start_of_quarter
                         and e1.end_of_quarter
group by e1.start_of_quarter, e1.end_of_quarter

Работает при условии, что есть таблица calendar1 с перечнем выходных dayoff=1.
14 июл 11, 13:51    [10973533]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
Vint
Member

Откуда: Москва
Сообщений: 4564
ecivgamer
тут много хороших и добрых людей которые за Вас решат Ваши задачи) я к ним редко отношусь) предпочитаю за это деньги получать всё таки)

почитайте про формат даты... там про выходные дни тоже можно додуматься а не городить таблицы. таблицы нужны для праздничных в основном) но это уже другая задача...
это маленький пинок, решающий часть Вашей задачи:
select max(sysdate+level)
from dual 
connect by level < (sysdate+365) - sysdate
group by to_char(sysdate+level,'Q YYYY')
14 июл 11, 14:31    [10973910]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10051
ecivgamer
Вот решение (к сожалению, дошел не своими мозгами, а получил ответ на другом форуме) :
Работает при условии, что есть таблица calendar1 с перечнем выходных dayoff=1.


In general, таблица calendar1 с перечнем выходных is right solution since next step you'll face is exclude holidays. But if you need to exclude выходныe only:

with t as (
           select  add_months(date '2009-10-01',level * 3)     start_of_quarter,
                   add_months(date '2010-01-01',level * 3) - 1 end_of_quarter
             from  dual
             connect by add_months(date '2010-01-01',level * 3) <= date '2013-01-01'
          )
select  start_of_quarter,
        end_of_quarter,
        case to_char(start_of_quarter,'dy','nls_date_language=english')
          when 'sun' then start_of_quarter + 1
          when 'sat' then start_of_quarter + 2
          else start_of_quarter
        end actual_start_of_quarter,
        case to_char(end_of_quarter,'dy','nls_date_language=english')
          when 'sun' then end_of_quarter - 2
          when 'sat' then end_of_quarter - 1
          else end_of_quarter
        end actual_end_of_quarter
  from  t
  order by start_of_quarter
/

START_OF_ END_OF_QU ACTUAL_ST ACTUAL_EN
--------- --------- --------- ---------
01-JAN-10 31-MAR-10 01-JAN-10 31-MAR-10
01-APR-10 30-JUN-10 01-APR-10 30-JUN-10
01-JUL-10 30-SEP-10 01-JUL-10 30-SEP-10
01-OCT-10 31-DEC-10 01-OCT-10 31-DEC-10
01-JAN-11 31-MAR-11 03-JAN-11 31-MAR-11
01-APR-11 30-JUN-11 01-APR-11 30-JUN-11
01-JUL-11 30-SEP-11 01-JUL-11 30-SEP-11
01-OCT-11 31-DEC-11 03-OCT-11 30-DEC-11
01-JAN-12 31-MAR-12 02-JAN-12 30-MAR-12
01-APR-12 30-JUN-12 02-APR-12 29-JUN-12
01-JUL-12 30-SEP-12 02-JUL-12 28-SEP-12

START_OF_ END_OF_QU ACTUAL_ST ACTUAL_EN
--------- --------- --------- ---------
01-OCT-12 31-DEC-12 01-OCT-12 31-DEC-12

12 rows selected.

SQL> 

SY.

Сообщение было отредактировано: 14 июл 11, 14:33
14 июл 11, 14:32    [10973913]     Ответить | Цитировать Сообщить модератору
 Re: конец квартала (исключая выходные дни)  [new]
ecivgamer
Member

Откуда:
Сообщений: 692
Vint
таблицы нужны для праздничных в основном)


Это как раз оно, я неправильно выразился. В таблице calendar dayoff=1 обозначает выходной или праздничный день.

Вопрос решен, всем спасибо.
14 июл 11, 15:09    [10974329]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить