Oracle Analytics窗口

时间:2012-03-30 20:34:11

标签: sql oracle analytic-functions oracle-analytics

给出下表

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()之外,我怎么能做到呢?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;