2017-05-29 7 views
0

Iグループは、数ヶ月 月ごとにグループ化するにはどうすればいいですか?

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)で見つけることができます。最後に投稿しました年、それはアクセス用ですが、原則はすべてのRDBMSで同じです –

+0

WHERE句などを含む有効なsqlで[mcve]を表示してください – OldProgrammer

答えて

1

Oracleはa good array of date manipulation functionsを持っています。この問題には2つの適切なものは、私たちはこれらの機能を組み合わせることができヶ月

与えられた数の日付をインクリメント二つの日付

  • ADD_MONTHS()間の月数を計算

    • MONTHS_BETWEEN()ですあなたのテーブルのレコードにまたがるすべての月のテーブルを生成します。次に、外部結合を使用して、条件付きで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 
      /
      
  • 関連する問題