フィールドの累積量または実行量を見つけて、ステージングからテーブルに挿入したい。私のステージング構造は次のようなものです。
ea_month id amount ea_year circle_id
April 92570 1000 2014 1
April 92571 3000 2014 2
April 92572 2000 2014 3
March 92573 3000 2014 1
March 92574 2500 2014 2
March 92575 3750 2014 3
February 92576 2000 2014 1
February 92577 2500 2014 2
February 92578 1450 2014 3
ターゲットテーブルを次のようにします。
ea_month id amount ea_year circle_id cum_amt
February 92576 1000 2014 1 1000
March 92573 3000 2014 1 4000
April 92570 2000 2014 1 6000
February 92577 3000 2014 2 3000
March 92574 2500 2014 2 5500
April 92571 3750 2014 2 9250
February 92578 2000 2014 3 2000
March 92575 2500 2014 3 4500
April 92572 1450 2014 3 5950
私は本当にこの結果を達成する方法について非常に混乱しています。 PostgreSQLを使用してこの結果を達成したいと思います。
誰でもこの結果セットを達成する方法を提案できますか?
基本的に、ここでは window function が必要です。これは最近の標準機能です。正規のウィンドウ関数に加えて、OVER
句を追加することにより、Postgresでany集計関数をウィンドウ関数として使用できます。
ここでの特別な難しさは、パーティションを取得して順序を正しく並べ替えることです。
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;
そして、noGROUP BY
ここに。
各行の合計は、パーティションの最初の行から現在の行まで計算されます-または、正確には マニュアル を引用します:
デフォルトのフレーミングオプションは
RANGE UNBOUNDED PRECEDING
で、RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
と同じです。ORDER BY
を使用すると、フレームをに設定します。パーティションのすべての行は、現在の行の最後のORDER BY
peerから始まります。
...これは、累積または現在の合計です。大胆な強調鉱山。
同じ(circle_id, ea_year, ea_month)
を持つ行は、このクエリでは "peers"です。これらはすべて、合計にすべてのピアが追加された同じ実行中の合計を示します。しかし、テーブルが(circle_id, ea_year, ea_month)
のUNIQUE
であると仮定すると、ソート順序は決定的であり、行にピアはありません。
現在、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;