Problem z tym, co masz teraz (poza dodatkowym cast()
i to_date()
wywołań) jest to, że w czwartej iteracji oba warunki są fałszywe, więc rekurencja się zatrzymuje; nie ma nic, co mogłoby sprawić, że trochę przeskoczy i znów się podniesie, w przeciwnym razie trwałoby to w nieskończoność. Nie sądzę, że można osiągnąć oba zakresy w ramach rekurencji.
Możesz umieścić ostatnią żądaną datę w części rekurencyjnej, a następnie przefiltrować dwa żądane zakresy:
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
Możesz zastąpić zapisane na stałe wartości parami dat rozpoczęcia i zakończenia. Jeśli zakresy mogą się nakładać lub drugi zakres może być (lub kończyć się) przed pierwszym, możesz wybrać wyższą datę:
WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1)
<= greatest(date '2015-01-27', date '2014-04-27')
... chociaż ma to sens tylko w przypadku zmiennych, a nie stałych wartości.