我们有一个表A
amount numeric,
serial int,
due_date date,
rate numeric,
mi numeric
样本数据:
amount. rate. due_date mi. serial
100000. 0.012. '2017-01-01' 3000. 1
100000. 0.012. '2017-02-01' 3000. 2
100000 0.012. '2017-03-01'. 2000. 3
.
.
.
金额列和行之间的比率是恒定的。
我想为表的每一行构造一个视图,如下所示:
serial opening int_amount. prncpl_amount. prncpl_os
1. amount opening*0.012 mi-int_amount. opening-prncpl_amount
2. previous(prncpl_os) opening*0.012. mi-int_amount. opening-prncpl_amount
.
.
我尝试使用滞后函数,但是由于prncpl_os不存在,因此失败。
编辑1:所需的结果将是
serial. opening. int_amount. prncpl_amount. prncpl_os
1. 100000. 1200 1800 98200
2. 98200. 1178.40. 1821.60. 96378.40
3. 96378.40. 1156.54. 843.46. 95534.94
编辑2:计算错误已按要求纠正...
答案 0 :(得分:3)
您需要一个recursive CTE:
WITH RECURSIVE next_ser AS (
SELECT
a.*,
lead(serial) OVER (ORDER BY serial) as next_serial
FROM a
),
cte AS (
SELECT
serial,
next_serial,
amount AS opening,
amount * rate AS int_amount,
mi - (amount * rate) AS prncpl_amount,
amount - mi + amount * rate AS prncpl_os
FROM
next_ser
WHERE serial = 1
UNION ALL
SELECT
a.serial,
a.next_serial,
c.prncpl_os,
c.prncpl_os * a.rate,
a.mi - (c.prncpl_os * rate),
c.prncpl_os - mi + c.prncpl_os * rate
FROM next_ser a
JOIN cte c ON a.serial = c.next_serial
)
SELECT
serial, opening, int_amount, prncpl_amount, prncpl_os
FROM cte
next_ser
CTE用于在lead()
window function的帮助下计算下一个序列(如果它们不是真正连续的),SELECT
的第一个UNION
语句)是起点,它将计算您的第一行。 UNION
的第二部分是CTE的递归部分。在该行中,最后一个递归步骤(JOIN cte
)与serial
id等于最后一个递归步骤的next_serial
的行结合在一起。先前的prncpl_os
值可以当作是使用当前值来计算的...