基本的に、ウィンドウ関数が必要です。これは最近の標準機能です。本物のウィンドウ関数に加えて、任意のを使用できます。 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;