6

私は Oracle の分析関数についてはかなりの経験がありますが、これは私を困惑させました。明白な解決策があれば、私は自分自身を蹴ります:)

別のテーブルに挿入、更新、および削除を記録する JOURNAL テーブルがあります。

ジャーナルであるテーブルは BOND_PAYMENTS で、PAYMENTS と BONDS の間のリンクを表します。特定の支払い (PAYMENT_ID で識別) から特定の債券 (BOND_NUMBER で識別) に割り当てられた金額 (AMOUNT) を格納します。さらに、「BON」、「PET」、またはその他のコードである可能性のある、結合のどの側面 (BOP_DOMAIN) に割り当てられたかを記録します。BOND_PAYMENTS テーブルには代理キー (BOP_ID) があります。

したがって、私のジャーナル テーブルには通常、各 BOP_ID に対して 1 つ以上のレコードがあります。最初に INSert、その後におそらくいくつかの UPDates、その後におそらく DELete が続きます。

JOURNAL テーブルは次のとおりです。

CREATE TABLE JOURNAL
( JN_DATE_TIME  DATE         NOT NULL,
  JN_OPERATION  VARCHAR2(3)  NOT NULL,
  BOP_ID        NUMBER(9)    NOT NULL,
  PAYMENT_ID    NUMBER(9)    NOT NULL,
  BOND_NUMBER   VARCHAR2(20) NOT NULL,
  BOP_DOMAIN    VARCHAR2(10) NOT NULL,
  AMOUNT        NUMBER(14,2) NOT NULL
);

サンプルデータは次のとおりです。

INSERT INTO JOURNAL VALUES (TO_DATE('01/01/2010','DD/MM/YYYY'),'INS',1242043,1003700,'9995/10','BON',1800);
INSERT INTO JOURNAL VALUES (TO_DATE('03/01/2010','DD/MM/YYYY'),'INS',1242046,1003700,'9998/10','BON',1700);
INSERT INTO JOURNAL VALUES (TO_DATE('04/01/2010','DD/MM/YYYY'),'INS',1242048,1003700,'9999/10','BON',1800);
INSERT INTO JOURNAL VALUES (TO_DATE('05/01/2010','DD/MM/YYYY'),'INS',1242052,1003700,'10003/10','BON',1600);
INSERT INTO JOURNAL VALUES (TO_DATE('08/01/2010','DD/MM/YYYY'),'INS',1242058,1003700,'9998/10','BON',100);
INSERT INTO JOURNAL VALUES (TO_DATE('09/01/2010','DD/MM/YYYY'),'UPD',1242058,1003700,'9998/10','PET',100);
INSERT INTO JOURNAL VALUES (TO_DATE('01/01/2010','DD/MM/YYYY'),'INS',2242043,1003701,'8995/10','BON',1800);
INSERT INTO JOURNAL VALUES (TO_DATE('02/01/2010','DD/MM/YYYY'),'INS',2242046,1003701,'8998/10','BON',1700);
INSERT INTO JOURNAL VALUES (TO_DATE('03/01/2010','DD/MM/YYYY'),'INS',2242048,1003701,'8999/10','BON',1800);
INSERT INTO JOURNAL VALUES (TO_DATE('04/01/2010','DD/MM/YYYY'),'INS',2242058,1003701,'8998/10','BON',100);
INSERT INTO JOURNAL VALUES (TO_DATE('05/01/2010','DD/MM/YYYY'),'UPD',2242046,1003701,'8998/10','BON',1500);
INSERT INTO JOURNAL VALUES (TO_DATE('06/01/2010','DD/MM/YYYY'),'INS',2242052,1003701,'9003/10','BON',1600);
INSERT INTO JOURNAL VALUES (TO_DATE('07/01/2010','DD/MM/YYYY'),'UPD',2242058,1003701,'8998/10','PET',200);

ここで、このジャーナル テーブルから完全なデータ セットを抽出する必要がありますが、形式はわずかに異なります。主な要件は、ジャーナル テーブルに BOP_DOMAIN を記録させたくないということです。これは必須ではありません。

各 BOND_PAYMENT レコードの合計金額の履歴を生成する必要があります。BOND_PAYMENT テーブル自体は、各レコードの最新のステータスしか表示されないため、使用できません。ジャーナルからこの情報をマイニングする必要があります。

SUM(amount) over(partition by payment_id, bond_number)個々の BOP_ID は数回更新される可能性があるため、単に取ることはできません。そのため、いつでも、その BOP_ID について記録された最新の金額のみを使用する必要があります。

上記のサンプル データが与えられた場合、生成されると予想される図を次に示します。

SELECT jn_date_time,
       jn_operation,
       bop_id,
       payment_id,
       bond_number,
       bop_domain,
       amount,
       ? as running_total
FROM   JOURNAL
ORDER BY jn_date_time;

サンプルデータと期待される結果

ここでは、2 つのサンプル支払いについて、左側にサンプル データを再現しました。右側には、期待される出力である「Running Total」があります。その横 (赤) は、各行の現在の合計を計算する方法のロジックです。

「現在の合計」は、仕訳入力の時点での、PAYMENT_ID と BOND_NUMBER の組み合わせの合計金額のスナップショットです。特定の BOP_ID が数回更新される可能性があることに注意してください。合計金額は、その BOP_ID の最新のレコードのみを考慮する必要があります。

機能するソリューションはすべて受け入れられますが、分析関数 (または分析関数の組み合わせ) がこれを解決するための最良の方法になると思います。

4

2 に答える 2

0
SELECT a.*,   
lag(amount,1) over (PARTITION BY bond_number ORDER BY 
payment_id,jn_date_time)recent_amount,   
amount + nvl(lag(amount,1) over (PARTITION BY bond_number ORDER BY  
payment_id,jn_date_time),0) running_total  
FROM JOURNAL a  
ORDER BY payment_id,jn_date_time  

このソリューションは、上記の質問に対して期待している正確な回答を提供し、それも単一のテーブルパスで提供します:)。

ラグ分析関数を使用して、bond_number/payment_id の組み合わせごとの金額の最新の値を取得し、その最近の金額の値を金額に追加して、現在の合計を取得しました... SIMPLE !!! ..それはありません:)

于 2015-09-04T09:35:57.127 に答える