Vấn đề với những gì bạn có bây giờ (ngoài cast()
bổ sung và to_date()
cuộc gọi) là ở lần lặp thứ tư, cả hai điều kiện đều sai nên phép đệ quy dừng lại; không có gì để làm cho nó bỏ qua một chút và chọn lại, nếu không nó sẽ tiếp tục mãi mãi. Tôi không nghĩ rằng bạn có thể đạt được cả hai phạm vi trong đệ quy.
Bạn có thể đặt ngày mới nhất mà bạn muốn bên trong phần đệ quy, rồi lọc hai phạm vi bạn muốn sau đó:
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
Bạn có thể thay thế các giá trị được mã hóa cứng bằng các cặp ngày bắt đầu và ngày kết thúc. Nếu các phạm vi có thể trùng lặp hoặc phạm vi thứ hai có thể (hoặc kết thúc) trước phạm vi đầu tiên, bạn có thể chọn ngày cao hơn:
WHERE ADD_MONTHS(TRUNC(cte_date, 'MONTH'), 1)
<= greatest(date '2015-01-27', date '2014-04-27')
... mặc dù điều đó chỉ có ý nghĩa với các biến, không phải giá trị cố định.