我正试图从现成的金融系统中产生一个“现金滞后”报告。我可以访问数据库(Oracle)。报告应将贷记应用于最早的借方,并计算生成账单与收到付款之间的天数差异。所有借方和贷方都存储在金融交易表的单个列中。适用的专栏是:
Column Name Type
----------- -------------
AMOUNT NUMERIC(15,2) --debits are positive, credits are negative
FT_ID CHAR(10)
ACCOUNT_ID CHAR(10)
ACCEPTED_DT DATETIME
所以对于像这样的表:
ACCOUNT_ID FT_ID AMOUNT ACCEPTED_DT
---------------------------------------
1 12345 100.00 12/01/2011
1 12346 -75.00 12/11/2011
1 12347 100.00 12/12/2011
1 12348 -50.00 12/16/2011
我想要取回的内容如下所示(编辑:更新以显示已应用的金额。我想要实际的信用额度,但可以根据信用卡的FT ID查找):
ACCOUNT_ID DEBIT_ID DEBIT_AMOUNT CREDIT_ID CREDIT_AMOUNT AGE
------------------------------------------------------------------
1 12345 75.00 12346 -75.00 10
1 12345 25.00 12348 -25.00 15
1 12347 25.00 12348 -25.00 4
1 12347 75.00 NULL NULL NULL
编辑:我公司选择的现成系统之美是支付应用程序是可配置的,这意味着信用卡与借记卡没有直接联系。我们首先将资金用于最早的债务,这是我试图在示例中显示的内容。第一笔付款完全适用于最早的债务。第二笔付款分为最老和第二老债务。这一直持续到所有学分都被应用为止。
编辑2 :对不起这对我来说似乎很难解释:)看看示例数据,FT 12346完全适用于FT 12345,在账户上留下了25美元的债务。然后,下一笔付款也将适用于此债务,任何剩余金额将应用于下一个最老的债务。跑步总数与我想要完成的完全不符,因为我需要知道比赛的每个“切片”的年龄:
编辑3 :上面的表格根本不清楚,抱歉。我已经更新了表格。
Debits Credits
+-----------------------+-------------------------+
| FT 12345 | FT 12346 |
| | |
| $100.00 | $75.00 |
| | |
| | |
| | |
| | |
| | |
| | |
| +-------------------------+
| | FT 12348 |
| | $50.00 |
| | +----->$25.00 towards 12345
+-----------------------|.........................|
| FT 12347 | |
| | +----->$25.00 towards 12347
| $100.00 +-------------------------+
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
+-----------------------+-------------------------+
我们有一个使用游标的解决方案,但是在整个金融交易表(约50米行)中,这非常慢。我想知道是否有办法在纯表格中重述问题以加快速度。我发现a recipe for genreating a running balance似乎是一个开始,但我不确定从那里开始。
答案 0 :(得分:1)
如果能够正确理解您的需求,可以使用分析来实现:
create table cred_deb (account_id integer, transaction_date date, amount number);
insert into cred_deb values (1, sysdate - 10, 100.00); -- bill of 100
insert into cred_deb values (1, sysdate - 9, -10.00); -- payment of 10
insert into cred_deb values (1, sysdate - 8, -80.00); -- payment of 80
insert into cred_deb values (1, sysdate - 5, 80.00); -- bill of 80
insert into cred_deb values(1, sysdate - 3, -80.00); -- payment of 80
-- 2nd account
insert into cred_deb values(2, sysdate - 3, 80.00); -- bill of 80
insert into cred_deb values(2, sysdate - 3, -80.00); -- payment of 80
select account_id,
transaction_date,
amount,
sum(amount) over( partition by account_id order by transaction_date) running_total
from cred_deb
order by account_id, transaction_date;
ACCOUNT_ID TRANSACTION_DATE AMOUNT RUNNING_TOTAL
---------------------- ------------------------- ---------------------- ----------------------
1 06-DEC-11 100 100
1 07-DEC-11 -10 90
1 08-DEC-11 -80 10
1 11-DEC-11 80 90
1 13-DEC-11 -80 10
2 13-DEC-11 80 80
2 13-DEC-11 -80 0
仔细观察您的示例,也许您希望将特定帐单的所有信用额与帐单金额分组到一行。如果您能够更清楚地描述您的内容,我认为分析将能够解决它。
编辑 - 增加了几天的年龄。
select account_id,
transaction_date,
amount,
sum(amount) over( partition by account_id order by transaction_date) running_total,
trunc(transaction_date) - max(case
when amount > 0 then
trunc(transaction_date)
else
null
end) over (partition by account_id order by transaction_date) age_in_days
from cred_deb
order by account_id, transaction_date