Điều này dễ dàng hơn trong SQL Server vì bạn có thể sử dụng CTE đệ quy. (Trên thực tế, bạn cũng có những thứ này trong Oracle 12C, vì vậy cách tiếp cận tương tự cũng hoạt động.)
with CTE as (
select event, startdate, enddate,
dateadd(day, 1 - day(startdate), startdate) as month_start
from t
union all
select event, startdate, enddate,
dateadd(month, 1, month_start)
from cte
while month_start <= enddate
)
select event, month_start,
((case when eomonth(enddate) = eomonth(month_start) -- last month
then day(enddate)
else day(eomonth(month_start))
end) -
(case when month_start < startdate -- first month
then day(startdate) - 1
else 0
end)
) as days_in_month
from cte;
Điều này mở rộng phạm vi ngày theo tháng cho mỗi sự kiện. Sau đó, nó sẽ tính toán số ngày trong tháng.
Theo mặc định, điều này sẽ hoạt động trong tối đa 100 tháng. Bạn có thể sử dụng maxrecursion
nếu bạn cần hỗ trợ thêm tháng.