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

PostgreSQLでの累積合計の計算

    基本的に、ウィンドウ関数が必要です。これは最近の標準機能です。本物のウィンドウ関数に加えて、任意のを使用できます。 OVERを追加して、Postgresのウィンドウ関数として関数を集約します。 条項。

    ここでの特別な難しさは、パーティションを取得して順序を正しく並べ替えることです。

    SELECT ea_month, id, amount, ea_year, circle_id
         , sum(amount) OVER (PARTITION BY circle_id
                             ORDER BY ea_year, ea_month) AS cum_amt
    FROM   tbl
    ORDER  BY circle_id, month;
    

    そしていいえ GROUP BY

    各行の合計は、パーティションの最初の行から現在の行まで計算されます。正確には、マニュアルを引用します。

    デフォルトのフレーミングオプションはRANGE UNBOUNDED PRECEDINGです。 、これはRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWと同じです。 。 ORDER BYを使用 、これにより、フレームがパーティションの開始から現在の行の最後のORDER BYまでのすべての行に設定されます。 ピア

    ...これはあなたが求めている累積または現在の合計です。大胆な強調鉱山。

    同じ(circle_id, ea_year, ea_month)の行 「ピア」 このクエリでは。これらはすべて同じ実行合計を示し、すべてのピアが合計に追加されます。しかし、あなたのテーブルはUNIQUEだと思います (circle_id, ea_year, ea_month) 、その場合、並べ替え順序は決定論的であり、ピアを持つ行はありません。

    Postgres 11は、新しいframe_exclusionでピアを含める/除外するツールを追加しました オプション。参照:

    • 同じグループに属していないすべての値を集計する

    さて、ORDER BY ... ea_month 月の名前の文字列では機能しません 。 Postgresはロケール設定に従ってアルファベット順にソートします。

    実際のdateがある場合 テーブルに保存されている値は、適切に並べ替えることができます。そうでない場合は、ea_yearを置き換えることをお勧めします およびea_month 単一の列を持つmon タイプdate あなたのテーブルに。

    • to_date()であなたが持っているものを変換します :

        to_date(ea_year || ea_month , 'YYYYMonth') AS mon
      
    • 表示するには、to_char()を使用して元の文字列を取得できます :

        to_char(mon, 'Month') AS ea_month
        to_char(mon, 'YYYY') AS ea_year
      

    不幸なデザインに固執している間、これはうまくいくでしょう:

    SELECT ea_month, id, amount, ea_year, circle_id
         , sum(amount) OVER (PARTITION BY circle_id ORDER BY mon) AS cum_amt
    FROM   (SELECT *, to_date(ea_year || ea_month, 'YYYYMonth') AS mon FROM tbl)
    ORDER  BY circle_id, mon;
    



    1. Oracle 11g XEにJavaをインストールする方法はありますか?

    2. Postgres9.4でJSONBタイプの列に対して更新操作を実行する方法

    3. SQLデータベースにアラビア文字を挿入する方法は?

    4. SQL Server 2017:Linuxで利用可能な機能