Расширяя ответ @ CaiusJard, вы можете получить начало финансового года с помощью:
add_months(trunc(add_months(get_date, -4), 'YYYY'), 4)
add_months(get_date, -4)
вычитает четыре месяца из даты начала, поэтому значениес января по апрель будет скорректирована на дату с сентября по декабрь предыдущего года .Так, например, 2018-03-11 станет 2017-11-11.Но даты, начиная с мая, останутся в том же году, поэтому, например, 2018-07-04 становится 2018-03-04.
Затем trunc(..., 'YYYY')
усекает это скорректированное значение допервый день своего года.Таким образом, 2018-03-11 становится 2017-11-11, который становится 2017-01-01;и 2018-07-04 становится 2018-03-04, который становится 2018-01-01.
Затем внешний add_months(..., 4)
добавляет четыре месяца назад к , что скорректированное значение.Таким образом, 2018-03-11 становится 2017-11-11, который становится 2017-01-01, который, наконец, становится 2017-05-01;и 2018-07-04 становится 2018-03-04, который становится 2018-01-01, который окончательно становится 2018-05-01.
Чтобы получить последний день финансового года, выможет сделать то же самое, но добавить дополнительные 12 месяцев в окончательном расчете - что даст вам начало следующего финансового года - и затем вычесть один день:
add_months(trunc(add_months(get_date, -4), 'YYYY'), 16) - 1
Подробнеео функциях add_months()
и trunc()
и о арифметике дат в документации.
Демонстрация с фиктивными датами вCTE, чтобы показать шаги настройки:
with your_table (get_date) as (
select add_months(date '2018-01-15', level)
from dual
connect by level <= 30
)
select get_date,
add_months(get_date, -4) as adjusted_month,
trunc(add_months(get_date, -4), 'YYYY') as adjusted_year,
add_months(trunc(add_months(get_date, -4), 'YYYY'), 4) as start_date,
add_months(trunc(add_months(get_date, -4), 'YYYY'), 16) - 1 as end_date
from your_table
order by get_date;
GET_DATE ADJUSTED_M ADJUSTED_Y START_DATE END_DATE
---------- ---------- ---------- ---------- ----------
2018-02-15 2017-10-15 2017-01-01 2017-05-01 2018-04-30
2018-03-15 2017-11-15 2017-01-01 2017-05-01 2018-04-30
2018-04-15 2017-12-15 2017-01-01 2017-05-01 2018-04-30
2018-05-15 2018-01-15 2018-01-01 2018-05-01 2019-04-30
2018-06-15 2018-02-15 2018-01-01 2018-05-01 2019-04-30
2018-07-15 2018-03-15 2018-01-01 2018-05-01 2019-04-30
...
2019-01-15 2018-09-15 2018-01-01 2018-05-01 2019-04-30
2019-02-15 2018-10-15 2018-01-01 2018-05-01 2019-04-30
2019-03-15 2018-11-15 2018-01-01 2018-05-01 2019-04-30
...
2020-02-15 2019-10-15 2019-01-01 2019-05-01 2020-04-30
2020-03-15 2019-11-15 2019-01-01 2019-05-01 2020-04-30
2020-04-15 2019-12-15 2019-01-01 2019-05-01 2020-04-30
2020-05-15 2020-01-15 2020-01-01 2020-05-01 2021-04-30
2020-06-15 2020-02-15 2020-01-01 2020-05-01 2021-04-30
2020-07-15 2020-03-15 2020-01-01 2020-05-01 2021-04-30
db <> fiddle
Как отмечено в других местах в комментариях, ваш исходный код содержит ошибку, потому что cast(<string> as date)
использует настройки NLS вашего сеанса, и строимая вами строка не соответствует этому параметру.Вы можете использовать to_date()
вместо case
, чтобы предоставить маску ожидаемого формата (см. Ответ @ alvalongo!).