Проверка запросов и процедур, приведенных здесь, не было сделано на 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
Создание DB2 FiscalDates таблицу и загрузите его с датами, указанными в вашем вопросе. –