Oracle ma dobry zestaw funkcji manipulacji datami . Dwa istotne dla tego problemu to
MONTHS_BETWEEN()
która oblicza liczbę miesięcy między dwiema datamiADD_MONTHS()
co zwiększa datę o podaną liczbę miesięcy
Możemy połączyć te funkcje, aby wygenerować tabelę wszystkich miesięcy uwzględnionych w rekordach Twojej tabeli. Następnie używamy sprzężenia zewnętrznego, aby warunkowo dołączyć rekordy z USER_INFO do tego kalendarza. Gdy żadne rekordy nie pasują do count(id)
będzie zero.
with cte as (
select max(trunc(created, 'MM')) as max_dt
, min(trunc(created, 'MM')) as min_dt
from user_info
)
, cal as (
select add_months(min_dt, (level-1)) as mth
from cte
connect by level <= months_between(max_dt, min_dt) + 1
)
select to_char(cal.mth, 'YYYY-MM') as operation
, count(id)
from cal
left outer join user_info
on trunc(user_info.created, 'mm') = cal.mth
group by rollup (cal.mth)
order by 1
/