Le problème avec ce que vous avez maintenant (à part l'extra cast()
et to_date()
appels) est qu'à la quatrième itération, les deux conditions sont fausses, donc la récursivité s'arrête ; il n'y a rien pour le faire sauter un peu et reprendre, sinon il continuerait pour toujours. Je ne pense pas que vous puissiez atteindre les deux plages dans la récursivité.
Vous pouvez mettre la dernière date souhaitée dans la partie récursive, puis filtrer les deux plages souhaitées par la suite :
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
Vous pouvez remplacer les valeurs codées en dur par vos paires de dates de début et de fin. Si les plages peuvent se chevaucher ou si la deuxième plage peut être (ou se terminer) avant la première, vous pouvez choisir la date la plus élevée :
WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1)
<= greatest(date '2015-01-27', date '2014-04-27')
... même si cela n'a de sens qu'avec des variables, pas avec des valeurs fixes.