2016-10-02 3 views
0

Я хотел бы получить последний день квартала, полугодия и года текущего финансового года в DB2. Наш Финансовый год начинается с 1 апреля и заканчивается 31 марта. Таким образом, если сегодняшняя дата - 02 октября 2016 года, дата окончания квартала будет 31 декабря 2016 года, а половина года - 31 марта 2017 года, а дата окончания года - 31 марта 2017 года. Аналогичным образом, если вводная дата - 07 мая 2016 года, то дата окончания квартала будет 30 июня 2016 года, половина дат будет 30 сентября 2016 года, а дата окончания года - 31 марта 2017 года.Как найти последний день квартала, полугодия и года текущего финансового года в DB2?

Я могу получить последнюю дату месяца, используя функцию last_day в DB2, но я не могу сделать то же самое для получения других 3 дат. Я буду признателен за любую помощь в этом.

+0

Создание DB2 FiscalDates таблицу и загрузите его с датами, указанными в вашем вопросе. –

ответ

0

Рассчитать количество месяцев в течение квартала (т.е. 1/2/3), а затем добавить 2 месяца для 1-го месяца четверти и 1 месяца для 2-го квартала (MOD(2-(MONTH(CURRENT_DATE)-1),3) = 0/1/2). Теперь ваш месяц всегда 3/6/9/12, и вы можете подать заявку last_day.

У меня нет системы DB2, чтобы проверить это, но синтаксис, кажется, как это:

LAST_DAY(CURRENT_DATE + (MOD(2-(CURRENT_DATE-1),3) MONTH)) 
0

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

SELECT MONTH(CURRENT DATE), -- returns 10 

     CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS, --return first day of current month 

     CASE WHEN 
       MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0 
       THEN 3 
      ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) 
     END, --months into the quarter, so 1 for first month, 2 for second month, 3 for last month 


     CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS + 
     (4 - CASE WHEN 
        MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0 
        THEN 3 
       ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) 
     END) MONTHS, --returns first day of next quarter 


     CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS + 
         (4 - CASE WHEN 
            MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) = 0 
             THEN 3 
           ELSE MOD(MONTH(CURRENT DATE - (DAY(CURRENT DATE) - 1) DAYS), 3) 
         END) MONTHS 
     - 1 DAY -- returns last day of current quarter 
FROM SYSIBM.SYSDUMMY1 

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

Я знаю, что это выглядит немного грязно, но это сработает. Я бы предложил использовать этот код для создания скалярной функции, которую вы можете легко использовать, чтобы найти квартал, и иметь что-то подобное в течение полугода и полного года.

Источники: Работа в качестве аналитика Business Intelligence с DB2 каждый день

0

Проверка запросов и процедур, приведенных здесь, не было сделано на DB2 для IBM я 7.3 [ака v7r3]

Нет указаний о том, как данные будут использоваться [для того, чтобы знать, в какой форме данные необходимы или могут быть предоставлены], но следующая пользовательская функция таблицы (UDTF) определяет некоторые константы, которые представляют отображение/корреляцию из входящего MONTH [необязательного DATE в качестве входных данных; по умолчанию - CURRENT DATE, если аргумент не указан], в месяцы как конца квартала, так и конца-половины и квартала; что отображение позволяет в течение некоторого достаточно простой арифметики дат, чтобы дать желаемые значения, не создавая при этом фактический [постоянный] календарь стол:

create function OUR_FINANCIAL_YEAR_DATES      
(input_date date default current date)      
returns table             
("Last_Day_Of_Quarter" /* for LD_QTR */ date    
, "Last_Day_Of_Half_Year" /* for LD_HALF */ date    
, "Last_Day_Of_Year"  /* for LD_YEAR */ date    
) language sql             
return               
with               
    moMap (mo, hAddMo, qAddMo, q) as (values     
     (12, 3 , 0 , 3), (11, 4 , 1 , 3), (10, 5 , 2 , 3) 
    , ( 9, 0 , 0 , 2), ( 8, 1 , 1 , 2), ( 7, 2 , 2 , 2) 
    , ( 6, 3 , 0 , 1), ( 5, 4 , 1 , 1), ( 4, 5 , 2 , 1) 
    , ( 3, 0 , 0 , 4), ( 2, 1 , 1 , 4), ( 1, 2 , 2 , 4)) 
, endFYdates (end_Qtr, end_Hyr, end_Fyr) as     
    (select              
     last_day(input_date + qAddMo MONTHS)  as Qtr_end 
    , last_day(input_date + hAddMo MONTHS)  as Hyr_end 
    , last_day(input_date + (qAddMo + (3 * (4 - q))  
           )  MONTHS)  as Fyr_end 
    from moMap as M           
    where mo = month(input_date )       
    )               
select end_Qtr, end_Hyr, end_Fyr        
from endFYdates            

Конечно скалярная функция пользователя (UDF) может достаточно легко использовать вышеупомянутую UDTF реализовать любое из этих значений; возможно, со вторым аргументом, определяющим, какое из этих значений DATE нужно вернуть.

with                 
    variousDates (dv) as (values         
    (date'2016-05-01'), (date'2016-05-02'), (date'2016-06-30') 
, (date'2016-07-02'), (date'2016-08-02'), (date'2016-09-30') 
, (date'2016-10-01'), (date'2016-11-02'), (date'2016-12-30') 
, (date'2017-01-02'), (date'2017-03-02'), (date'2017-03-30')) 
select vdv.*, fyv.*             
    , dec(quarter(vdv.dv - 3 months) , 1) as qtr    
from variousDates as vdv            
, lateral               
    (select s.* from table(OUR_FINANCIAL_YEAR_DATES(vdv.dv)) as s  
) as fyv               
order by 1               
; -- a likeness of a report from the above query: 
DV   LAST_00001 LAST_00002 LAST_00003 QTR 
2016-05-01 2016-06-30 2016-09-30 2017-03-31 1 
2016-05-02 2016-06-30 2016-09-30 2017-03-31 1 
2016-06-30 2016-06-30 2016-09-30 2017-03-31 1 
2016-07-02 2016-09-30 2016-09-30 2017-03-31 2 
2016-08-02 2016-09-30 2016-09-30 2017-03-31 2 
2016-09-30 2016-09-30 2016-09-30 2017-03-31 2 
2016-10-01 2016-12-31 2017-03-31 2017-03-31 3 
2016-11-02 2016-12-31 2017-03-31 2017-03-31 3 
2016-12-30 2016-12-31 2017-03-31 2017-03-31 3 
2017-01-02 2017-03-31 2017-03-31 2017-03-31 4 
2017-03-02 2017-03-31 2017-03-31 2017-03-31 4 
2017-03-30 2017-03-31 2017-03-31 2017-03-31 4 
******** End of data ********      

Следующая UDTF вычисляет оконечные-Quarter для заданного значения DATE в качестве входных данных [для CURRENT_DATE, если нет аргументов передается], но дополнительно вычисляет и обеспечивает Quarter Start-Of- и значения конечного Of_Quarter за каждый квартал от расчетной даты, а также обеспечивает вычисленный результат для конца-тайма, End-Of-года, и четверть заданного значения DATE:

create function THE_FINANCIAL_YEAR_DATES   
(input_date date default current date)   
returns table          
(LastOfQtr    /* for LD_QTR */ date 
, LastOfHalf    /* for LD_HALF */ date 
, LastOfYear    /* for LD_YEAR */ date 
, NumberQtr    /* for NO_QTR */ dec(1) 
, FirstOfQ1    /* for FD_Q1 */ date 
, Last_OfQ1    /* for LD_Q1 */ date 
, FirstOfQ2    /* for FD_Q2 */ date 
, Last_OfQ2    /* for LD_Q2 */ date 
, FirstOfQ3    /* for FD_Q3 */ date 
, Last_OfQ3    /* for LD_Q3 */ date 
, FirstOfQ4    /* for FD_Q4 */ date 
, Last_OfQ4    /* for LD_Q4 */ date 
) language sql          
return                
with                
    endCurQtr (ecq , q) as           
    (values              
     (LAST_DAY( input_date          
        + (MOD(1 - MONTH(input_date)     
          , 3) + 2         
        ) MONTHS          
       )             
     , DEC(QUARTER(input_date - 3 MONTHS), 1)     
     )               
    )                
, curFYdates (q, ecq, sQ1, eQ1, sQ2, eQ2, sQ3, eQ3, sQ4, eQ4, eHY) as 
    (select q, ecq,             
     (ecq + 1 day) - ( 3 * (q ) ) months    
    , last_day((ecq) - ( 3 * (q - 1) ) months)    
    , (ecq + 1 day) - ( 3 * (q - 1) ) months    
    , last_day((ecq) - ( 3 * (q - 2) ) months)   
    , (ecq + 1 day) - ( 3 * (q - 2) ) months   
    , last_day((ecq) - ( 3 * (q - 3) ) months)   
    , (ecq + 1 day) - ( 3 * (q - 3) ) months   
    , last_day((ecq) - ( 3 * (q - 4) ) months)   
    , last_day((ecq) - ( 3 * (q -       
      case when q>2 then 4 else 2 end) ) months)   
    from endCurQtr            
)                
select ecq, eHY, eQ4, q, sQ1, eQ1, sQ2, eQ2, sQ3, eQ3, sQ4, eQ4 
from curFYdates             
Смежные вопросы