2017-05-29 76 views
0

我组我的表按月份如何按月包括所有月份?

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 

但记录并不包括所有的月份。
我想输出到包括所有的几个月里,用默认值显示在输出缺少的:

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

寻找*日历表*,这里有很多这样的问题。你可以找到灵感[这个完整的解决方案](https://stackoverflow.com/questions/36789953/access-sql-count-number-of-people-group-by-week-number/36792224#36792224)我发布最后年,这是为Access,但所有RDBMS的原理是相同的 –

+0

请用有效的sql显示[mcve],包括WHERE子句等。 – OldProgrammer

回答

1

甲骨文a good array of date manipulation functions。这两个相关的人对于这个问题是

  • MONTHS_BETWEEN()它计算月的两个日期
  • ADD_MONTHS()其中由给定数月

的我们可以结合这些功能增加的日期之间的数生成表格记录中所有月份的表格。然后,我们使用外部联接来有条件地将来自USER_INFO的记录连接到该日历。当没有记录匹配时count(id)将为零。

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 
/