Проблемът с това, което имате сега (освен допълнителния cast()
и to_date()
calls) е, че на четвъртата итерация и двете условия са неверни, така че рекурсията спира; няма нищо, което да го накара да прескочи малко и да вземе отново, в противен случай ще продължи вечно. Не мисля, че можете да постигнете и двата диапазона в рамките на рекурсията.
Можете да поставите най-новата дата, която искате, в рекурсивната част и след това да филтрирате двата диапазона, които искате след това:
WITH CTE_Dates (cte_date) AS (
SELECT date '2014-01-27' from dual
UNION ALL
SELECT ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1)
FROM CTE_Dates
WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1) <= date '2015-01-27'
)
SELECT * from CTE_Dates
WHERE cte_date BETWEEN date '2014-01-27' AND date '2014-04-27'
OR cte_date BETWEEN date '2014-11-27' AND date '2015-01-27';
CTE_DATE
---------
27-JAN-14
01-FEB-14
01-MAR-14
01-APR-14
01-DEC-14
01-JAN-15
6 rows selected
Можете да замените твърдо кодираните стойности с вашите двойки начална и крайна дата. Ако диапазоните може да се припокриват или вторият диапазон може да е (или да завърши) преди първия, можете да изберете по-високата дата:
WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1)
<= greatest(date '2015-01-27', date '2014-04-27')
... въпреки че това има смисъл само с променливи, а не с фиксирани стойности.