2

次の表を考えると

PAYMENT_Date  TRANSACTION_TYPE     PAYMENT_AMT
1/1/2012      P                    184366     
1/1/2012      R                    -5841     
1/2/2012      P                    941
1/3/2012      P                    901
1/3/2012      R                    5841

および次のクエリ:

select  payment_date, transaction_type, payment_amt,
        SUM(payment_amt) OVER(ORDER BY payment_date, transaction_type 
            RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS RUNNING_BALANCE
from    TABLE;

次の結果が得られます。

PAYMENT_Date  TRANSACTION_TYPE     PAYMENT_AMT  RUNNING_BALANCE
1/1/2012      P                    184366       0
1/1/2012      R                    -5841        -184366
1/2/2012      P                    941          -178525
1/3/2012      P                    901          -179466
1/3/2012      R                    5841         -180367

期待される:

PAYMENT_Date  TRANSACTION_TYPE     PAYMENT_AMT  RUNNING_BALANCE
1/1/2012      P                    184366       0
1/1/2012      R                    -5841        184366
1/2/2012      P                    941          178525
1/3/2012      P                    901          179466
1/3/2012      R                    5841         180367

RUNNING_BALANCE が負の数として返されるのはなぜですか? 明らかな abs() 以外に、どうすればそうしないことができますか?

4

2 に答える 2

6

まず、投稿したデータとクエリは、表示されている出力を生成するようには見えません。そのため、どこかにある種のコピーアンドペーストエラーがあります

SQL> with t as (
  2    select date '2012-01-01' payment_date, 'P' transaction_type, 184366 payment_amt from dual union all
  3    select date '2012-01-01', 'R', -5841 from dual union all
  4    select date '2012-01-02', 'P', 941 from dual union all
  5    select date '2012-01-03', 'P', 901 from dual union all
  6    select date '2012-01-03', 'R', 5841 from dual
  7  )
  8  select  payment_date, transaction_type, payment_amt,
  9          SUM(payment_amt) OVER(ORDER BY payment_date, transaction_type
 10              RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS RUNNING_BALANCE
 11  from    T;

PAYMENT_D T PAYMENT_AMT RUNNING_BALANCE
--------- - ----------- ---------------
01-JAN-12 P      184366          186208
01-JAN-12 R       -5841            1842
02-JAN-12 P         941            7683
03-JAN-12 P         901            6742
03-JAN-12 R        5841            5841

通常、実行中のバランスは、RANGE BETWEEN句を省略するだけで行われます。

SQL> ed
Wrote file afiedt.buf

  1  with t as (
  2    select date '2012-01-01' payment_date, 'P' transaction_type, 184366 payment_amt from dual union all
  3    select date '2012-01-01', 'R', -5841 from dual union all
  4    select date '2012-01-02', 'P', 941 from dual union all
  5    select date '2012-01-03', 'P', 901 from dual union all
  6    select date '2012-01-03', 'R', 5841 from dual
  7  )
  8  select  payment_date, transaction_type, payment_amt,
  9          SUM(payment_amt) OVER(ORDER BY payment_date, transaction_type) AS RUNNING_BALANCE
 10* from    T
SQL> /

PAYMENT_D T PAYMENT_AMT RUNNING_BALANCE
--------- - ----------- ---------------
01-JAN-12 P      184366          184366
01-JAN-12 R       -5841          178525
02-JAN-12 P         941          179466
03-JAN-12 P         901          180367
03-JAN-12 R        5841          186208

ただし、あなたの場合、実行中の残高から現在の行の支払いを除外したいようです。それは少し奇妙な購入です。追加で追加することでそれを行うことができますLAG

SQL> ed
Wrote file afiedt.buf

  1  with t as (
  2    select date '2012-01-01' payment_date, 'P' transaction_type, 184366 payment_amt from dual union all
  3    select date '2012-01-01', 'R', -5841 from dual union all
  4    select date '2012-01-02', 'P', 941 from dual union all
  5    select date '2012-01-03', 'P', 901 from dual union all
  6    select date '2012-01-03', 'R', 5841 from dual
  7  )
  8  select  payment_date,
  9          transaction_type,
 10          payment_amt,
 11          NVL( LAG(running_balance) OVER(ORDER BY payment_date,
 12                                                  transaction_type), 0) new_running_balance
 13    from (select payment_date,
 14                 transaction_type,
 15                 payment_amt,
 16                 SUM(payment_amt) OVER(ORDER BY payment_date,
 17                                                transaction_type) AS RUNNING_BALANCE
 18*           from t)
SQL> /

PAYMENT_D T PAYMENT_AMT NEW_RUNNING_BALANCE
--------- - ----------- -------------------
01-JAN-12 P      184366                   0
01-JAN-12 R       -5841              184366
02-JAN-12 P         941              178525
03-JAN-12 P         901              179466
03-JAN-12 R        5841              180367
于 2012-03-30T20:44:52.190 に答える
5

変更する必要があると思います:

RANGE  BETWEEN   CURRENT ROW           AND   UNBOUNDED FOLLOWING`  

に:

ROWS   BETWEEN   UNBOUNDED PRECEDING   AND   1 PRECEDING

SQLfiddleでテストします。

SELECT  payment_date, transaction_type, payment_amt,
        COALESCE( SUM(payment_amt) 
                  OVER( ORDER BY payment_date, transaction_type
                        ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
                , 0)  AS RUNNING_BALANCE
FROM    T;
于 2012-03-30T20:47:39.913 に答える