期初和期末余额查询

时间:2017-02-05 16:30:02

标签: sql oracle

我正在尝试根据客户及其每日明智的cr / dr交易来计算期初和期末余额。

关闭=开始+ db -cr和

如果上一个日期结束,

开盘,如果该客户没有以前的记录,则应该为0.

create table pj_test_cr_dr(
    cst_name varchar2(100),
    txn_dt number(8),
    cr_amt number(22,7),
    dr_amt number(22,7)
    );

insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-5,'yyyymmdd'),200,0);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-5,'yyyymmdd'),300,0);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-5,'yyyymmdd'),0,2000);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-4,'yyyymmdd'),100,0);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-4,'yyyymmdd'),400,0);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-4,'yyyymmdd'),0,2000);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-3,'yyyymmdd'),2000,2000);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-3,'yyyymmdd'),4000,2000);
insert into pj_test_cr_dr 
    values ('c1', to_char(sysdate-2,'yyyymmdd'),5000,0);
commit;

select  cst_name, txn_dt, sum(dr_amt) dr,sum(cr_amt) cr
    from pj_test_cr_dr 
    group by cst_name, txn_dt 
    order by 1,2;

查询输出

enter image description here

预期结果:

enter image description here

此致

2 个答案:

答案 0 :(得分:0)

试试这个:

select
    cst_name,
    debit,
    credit,
    lag(closing,1,0) over (partition by cst_name order by txn_dt) opening,
    closing
from (
    select 
        cst_name,
        txn_dt,
        sum(dr_amt) debit,
        sum(cr_amt) credit,
        sum(sum(dr_amt - cr_amt)) over (partition by cst_name order by txn_dt) closing
    from pj_test_cr_dr
    where txn_dt > 20170130
    group by cst_name, txn_dt
) t;

另请注意partition by cst_name。我认为您希望将不同客户的价值分开。

答案 1 :(得分:0)

这是一种方法 - 一个查询(没有子查询),只有分析函数(不与聚合混合 - 除了选择distinct,因为每天可能有多个交易)

select distinct cst_name, txn_dt,
         coalesce( sum(dr_amt - cr_amt) over (partition by cst_name order by txn_dt 
             range between unbounded preceding and 1 preceding), 0 )       as op_bal,
         sum(dr_amt) over (partition by cst_name, txn_dt)                  as daily_dr,
         sum(cr_amt) over (partition by cst_name, txn_dt)                  as daily_cr,
         sum(dr_amt - cr_amt) over (partition by cst_name order by txn_dt) as cl_bal
from     pj_test_cr_dr
order by cst_name, txn_dt   --   if needed
;

CST_NAME     TXN_DT     OP_BAL   DAILY_DR   DAILY_CR     CL_BAL
-------- ---------- ---------- ---------- ---------- ----------
c1         20170131          0       2000        500       1500
c1         20170201       1500       2000        500       3000
c1         20170202       3000       4000       6000       1000
c1         20170203       1000          0       5000      -4000