質問

このようなテーブルがあります(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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top