How to group by month including all months?

一世执手 提交于 2021-02-05 11:28:46

问题


I group my table by months

  SELECT TO_CHAR (created, 'YYYY-MM') AS operation, COUNT (id)
    FROM user_info
   WHERE created IS NOT NULL
GROUP BY ROLLUP (TO_CHAR (created, 'YYYY-MM'))

2015-04 1
2015-06 10
2015-08 22
2015-09 8
2015-10 13
2015-12 5
2016-01 25
2016-02 37
2016-03 24
2016-04 1
2016-05 1
2016-06 2
2016-08 2
2016-09 7
2016-10 103
2016-11 5
2016-12 2
2017-04 14
2017-05 2
        284

But the records don't cover all the months.
I would like the output to include all the months, with the missing ones displayed in the output with a default value:

2017-01 ...
2017-02 ...
2017-03 ZERO
2017-04 ZERO
2017-05 ...

回答1:


Oracle has a good array of date manipulation functions. The two pertinent ones for this problem are

  • MONTHS_BETWEEN() which calculates the number of months between two dates
  • ADD_MONTHS() which increments a date by the given number of months

We can combine these functions to generate a table of all the months spanned by your table's records. Then we use an outer join to conditionally join records from USER_INFO to that calendar. When no records match count(id) will be 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
/


来源:https://stackoverflow.com/questions/44243458/how-to-group-by-month-including-all-months

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!