with t as ( select to_date('03-05-2010','dd-mm-yyyy') d1, to_date('26-08-2010','dd-mm-yyyy') d2 from dual ) -- select decode(level,1,d1,trunc(add_months(d1,level-1),'mm')) as date_from, case when add_months(trunc(d1,'mm'),level)>d2 then d2 else last_day(add_months(d1,level-1)) end date_to from t connect by add_months(trunc(d1,'mm'),level-1) < d2; DATE_FROM DATE_TO ----------- ----------- 03.05.2010 31.05.2010 01.06.2010 30.06.2010 01.07.2010 31.07.2010 01.08.2010 26.08.2010
Если хотим, чтобы в период входил 1 день последнего месяца, то :
with t as ( select to_date('03-05-2010','dd-mm-yyyy') d1, to_date('01-08-2010','dd-mm-yyyy') d2 from dual ) -- select decode(level,1,d1,trunc(add_months(d1,level-1),'mm')) as date_from, case when add_months(trunc(d1,'mm'),level)>d2 then d2 else last_day(add_months(d1,level-1)) end date_to from t connect by add_months(trunc(d1,'mm'),level-1) <= d2; DATE_FROM DATE_TO ----------- ----------- 03.05.2010 31.05.2010 01.06.2010 30.06.2010 01.07.2010 31.07.2010 01.08.2010 01.08.2010
connect by add_months(d1,level-1) < d2;
немножко некорректно, необходимо именно не d1, а trunc(d1, 'mm'), иначе пропадет последний период при условии что число начала периода выше числа из окончания периода.
@underchronos
А можно пример входных данных для неправильной работы запроса?
Конечно:
’27-05-2010′ and ’26-08-2010′
Результат получится:
27.05.2010 31.05.2010
01.06.2010 30.06.2010
01.07.2010 26.08.2010
— два последних периода вместе схлопнулись из-за того, что 27.08.2010 > 26.08.2010, а при корректировке 01.08.2010 <= 26.08.2010
— надо даже еще условие не '<' , а '<=' иначе схлопнется при условии, что дни одинаковые в условиях.
— кстати, как вариант условия выхода из "рекурсивного вызова" — использование функции months_between (кому как нравится).
Кстати, отличный блог. Опыта у меня в программировании под Оркала никакого, но в администрирования есть. Интересные заметки есть.
@underchronos
Спасибо. Учёл замечание.
Если на вход подать больше одной строки:
результаты дублируются. Как побороть?
Не «на месяца», автор, это не по-русски. Это по-бухгалтерски. Правильно будет — на месяцы.
не знаю как, но если добавить два волшебных сравнения, то работает
столбец «id» (название неважно) надо добавить в таблицу «t» и обеспечить, чтобы у каждого интервала оно было уникальным.