sql >> データベース >  >> RDS >> PostgreSQL

月ごとの値の累積合計、欠落している月を埋める

    これは他の質問と非常に似ていますが、最良の質問は依然として注意が必要です。

    基本的なクエリ ランニングサムをすばやく取得するには:

    SELECT to_char(date_trunc('month', date_added), 'Mon YYYY') AS mon_text
         , sum(sum(qty)) OVER (ORDER BY date_trunc('month', date_added)) AS running_sum
    FROM   tbl
    GROUP  BY date_trunc('month', date_added)
    ORDER  BY date_trunc('month', date_added);
    

    トリッキーな部分は、不足している月を埋めることです。 :

    WITH cte AS (
       SELECT date_trunc('month', date_added) AS mon, sum(qty) AS mon_sum
       FROM   tbl
       GROUP  BY 1
       )
    SELECT to_char(mon, 'Mon YYYY') AS mon_text
         , sum(c.mon_sum) OVER (ORDER BY mon) AS running_sum
    FROM  (SELECT min(mon) AS min_mon FROM cte) init
         , generate_series(init.min_mon, now(), interval '1 month') mon
    LEFT   JOIN cte c USING (mon)
    ORDER  BY mon;
    

    暗黙のCROSS JOIN LATERAL Postgres9.3以降が必要です。これは、テーブルの最初の月から始まります。
    特定の月から始める

    WITH cte AS (
       SELECT date_trunc('month', date_added) AS mon, sum(qty) AS mon_sum
       FROM   tbl
       GROUP  BY 1
       )
    SELECT to_char(mon, 'Mon YYYY') AS mon_text
         , COALESCE(sum(c.mon_sum) OVER (ORDER BY mon), 0) AS running_sum
    FROM   generate_series('2015-01-01'::date, now(), interval '1 month') mon
    LEFT   JOIN cte c USING (mon)
    ORDER  BY mon;

    SQLフィドル。

    異なる年からの月を離しておく。あなたはそれを求めていませんでしたが、おそらくそれを望んでいるでしょう。

    「月」は、現在のセッションのタイムゾーン設定にある程度依存することに注意してください。詳細:

    関連:




    1. MYSQLでWHERE句として文字列を渡す方法

    2. MySQLで週ごとにグループ化

    3. OracleへのSSIS接続

    4. 値を減算して列を更新します