基于未结金额的比例分布

时间:2018-06-26 07:16:58

标签: sql postgresql postgresql-10

以下数据表示两笔贷款的进出交易。 交易ID(t_id)代表交易事件发生的顺序。

+---------+------+-----+--------+
| loan_id | t_id | amt | t_type |
+---------+------+-----+--------+
|       1 |    1 | 100 | OUT    |
|       1 |    2 |  20 | IN     |
|       1 |    3 |  30 | IN     |
|       1 |    4 | 150 | OUT    |
|       1 |    5 |  15 | IN     |
|       1 |    6 |  25 | IN     |
|       1 |    7 |  40 | OUT    |
|       1 |    8 | 200 | IN     |
|       2 |    1 | 150 | OUT    |
|       2 |    2 |  50 | OUT    |
|       2 |    3 | 120 | IN     |
|       2 |    4 |  20 | OUT    |
|       2 |    5 | 100 | IN     |
+---------+------+-----+--------+

目标是在收款交易事件发生时,根据收款交易未清金额按比例将收款分配给收款。每笔贷款应单独处理。
应遵循以下逻辑:
loan_id:1
1)传入事务2和3应该100%分配给传出事务1,因为当时它只是传出事务。
2)应在传出交易1和4之间为传入交易5分配25%/ 75%。(交易1的未清金额为50,因为交易2和3偿还了50,交易4的未清金额为150)
3)应在传出交易1和4之间为传入交易6分配25%/ 75%(交易1未结金额为46.25,交易4未结金额为138.75)
4)传入事务8应该在传出事务1之间分配20%/ 60%/ 20%; 4&7(交易1; 4&7未清金额分别是40、120和40)

我们可以假设总进货金额和运行总进货金额始终小于或等于未结总进货金额。

这是最终结果的样子:

+---------+---------+----------+---------------+
| loan_id | in_t_id | out_t_id | allocated_amt |
+---------+---------+----------+---------------+
|       1 |       2 |        1 | 20            |
|       1 |       3 |        1 | 30            |
|       1 |       5 |        1 | 3.75          |
|       1 |       5 |        4 | 11.25         |
|       1 |       6 |        1 | 6.25          |
|       1 |       6 |        4 | 18.75         |
|       1 |       8 |        1 | 40            |
|       1 |       8 |        4 | 120           |
|       1 |       8 |        7 | 40            |
|       2 |       3 |        1 | 90            |
|       2 |       3 |        2 | 30            |
|       2 |       5 |        1 | 60            |
|       2 |       5 |        2 | 20            |
|       2 |       5 |        4 | 20            |
+---------+---------+----------+---------------+

链接到SQL小提琴:http://www.sqlfiddle.com/#!17/9eecb/16623
生成了14行的所有组合,但是未分配。

目前,我不确定是否可以创建SQL来生成这种逻辑。
我尝试使用窗口函数来实现此目标,但没有任何运气,因为始终需要根据以前的比例分布来知道未结清的未清金额。
也许可以创建递归查询来涵盖此逻辑。

1 个答案:

答案 0 :(得分:-1)

我认为,如果在每个IN事务之后创建一个历史表来存储分布,那么下一个IN事务可以重用计算所得的值,而不是尝试动态地计算它们,这样会更容易。为此,您将需要一个INSERT触发器-请查看SQLfiddle

app.js