Прежде всего, решение, предоставленное @ AP C, необходимо и достаточно для решения проблемы, представленной OP. Однако есть альтернатива, особенно. так как я сожалею о манипуляции со строками для дат. Преобразуйте строку в дату и с этого момента выполняйте ВСЕ дальнейшую обработку с использованием функций даты (или отметки времени, если необходимо). Нет НИКАКОЙ причины конвертировать дату в строку, за исключением окончательного отображения или экспорта. Поэтому я предлагаю следующую альтернативу для последующих зрителей. Представленная проблема сводится к следующему: Учитывая дату и целевой месяц - если месяц с датой совпадает с указанным месяцем позже, верните первый из целевого месяца. - если месяц даты предшествует целевому месяцу, верните первое целевого месяца в предыдущем году.
alter session set nls_date_format = 'yyyy-mm-dd';
with t as (select to_date('02/11/20','mm/dd/rr') src_dte, 1 tgt_mon from dual union all
select to_date('2020-02-11'), 2 from dual union all
select to_date('11-Feb-2020','dd-mon-yyyy'), 3 from dual
)
select t.src_dte, tgt_mon
, case when extract(month from t.src_dte) >= t.tgt_mon
then add_months(trunc(t.src_dte, 'year'), t.tgt_mon-1)
else add_months(trunc(t.src_dte, 'year'), t.tgt_mon-1-12)
end as effective_date
from t;
Как это работает. Все функции даты возвращают действительную дату. 1. trun c (src_date), 'year') возвращает дату 01-Jan- year 2. Из вышеперечисленного добираться до нужного месяца просто добавляя необходимое количество месяцев (0-11). Так как целью является tgt_mon вычитание 1, а затем добавление к результату trun c дает 1-tgt_mon- год . 3. За предыдущий год возьмите тот же результат сверху и вычтите 1 год (12 месяцев). Нет функции вычитать месяцы, поэтому просто добавьте -12. Это дает 1-tgt_mon-year-1 .
Я считаю, что это лучший метод обработки дат, чем манипулирование строками, но это только мое мнение. Бери если за то что будешь.