テーブル内のグループ化されたレコードごとの積算合計
-
22-07-2019 - |
質問
このようなテーブルがあります(Oracle、10)
Account Bookdate Amount
1 20080101 100
1 20080102 101
2 20080102 200
1 20080103 -200
...
必要なのは、アカウントascおよびBookdate ascごとのアカウント順でグループ化された新しいテーブルで、次のような積算合計フィールドがあります:
Account Bookdate Amount Running_total
1 20080101 100 100
1 20080102 101 201
1 20080103 -200 1
2 20080102 200 200
...
簡単な方法はありますか?
事前に感謝します。
解決
追加のテーブルが本当に必要ですか?
単純なクエリを使用して必要なデータを取得できます。テーブルのように表示する場合は、当然ビューとして作成できます。
これにより、探しているデータが取得されます。
select
account, bookdate, amount,
sum(amount) over (partition by account order by bookdate) running_total
from t
/
これにより、データをテーブルであるかのように表示するビューが作成されます。
create or replace view t2
as
select
account, bookdate, amount,
sum(amount) over (partition by account order by bookdate) running_total
from t
/
テーブルが本当に必要な場合、常に更新する必要があるということですか?または1つだけですか?もちろん、1回限りの場合は、「テーブルを選択として作成」するだけです。上記のクエリを使用します。
使用したテストデータ:
create table t(account number, bookdate date, amount number);
insert into t(account, bookdate, amount) values (1, to_date('20080101', 'yyyymmdd'), 100);
insert into t(account, bookdate, amount) values (1, to_date('20080102', 'yyyymmdd'), 101);
insert into t(account, bookdate, amount) values (1, to_date('20080103', 'yyyymmdd'), -200);
insert into t(account, bookdate, amount) values (2, to_date('20080102', 'yyyymmdd'), 200);
commit;
編集:
追加を忘れました。テーブルを順序付けすることを指定した-これは実際には意味がなく、クエリ/ビューが必要であることを本当に意味すると思います-順序付けは、固有の何かではなく、実行するクエリの結果ですテーブル(Index Organized Tablesなどを無視)。
他のヒント
この非常に重要な警告から始めます。このデータを保持するテーブルを作成しないでください。そうするとき、あなたはそれを維持する必要があることに気付くでしょう、そしてそれは終わりのない頭痛になります。必要に応じて、追加の列を返すビューを作成します。データウェアハウスを使用している場合、おそらくこのようなことをしますが、インデックスで必要なパフォーマンスが得られない場合を除き、ビューの側でエラーが発生します。まともなハードウェアなど
必要な方法で行を返すクエリを次に示します。
SELECT
Account,
Bookdate,
Amount,
(
SELECT SUM(Amount)
FROM My_Table T2
WHERE T2.Account = T1.Account
AND T2.Bookdate <= T1.Bookdate
) AS Running_Total
FROM
My_Table T1
別の可能な解決策は次のとおりです。
SELECT
T1.Account,
T1.Bookdate,
T1.Amount,
SUM(T2.Amount)
FROM
My_Table T1
LEFT OUTER JOIN My_Table T2 ON
T2.Account = T1.Account AND
T2.Bookdate <= T1.Bookdate
GROUP BY
T1.Account,
T1.Bookdate,
T1.Amount
パフォーマンスの両方をテストし、どちらがより適切かを確認します。また、私はあなたが与えた例を超えてそれらを徹底的にテストしていないので、いくつかのエッジケースを必ずテストしてください。
前回の質問と同様に、分析を使用します:
create table accounts
( account number(10)
, bookdate date
, amount number(10)
);
delete accounts;
insert into accounts values (1,to_date('20080101','yyyymmdd'),100);
insert into accounts values (1,to_date('20080102','yyyymmdd'),101);
insert into accounts values (2,to_date('20080102','yyyymmdd'),200);
insert into accounts values (1,to_date('20080103','yyyymmdd'),-200);
commit;
select account
, bookdate
, amount
, sum(amount) over (partition by account order by bookdate asc) running_total
from accounts
order by account,bookdate asc
/
出力:
ACCOUNT BOOKDATE AMOUNT RUNNING_TOTAL
---------- -------- ---------- -------------
1 01-01-08 100 100
1 02-01-08 101 201
1 03-01-08 -200 1
2 02-01-08 200 200