Esto es más fácil en SQL Server porque puede usar un CTE recursivo. (En realidad, también tiene estos en Oracle 12C, por lo que funciona el mismo enfoque).
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;
Esto amplía el rango de fechas por mes para cada evento. Luego calcula el número de días del mes.
Por defecto, esto funcionará hasta por 100 meses. Puedes usar maxrecursion
opción si necesita soporte por más meses.