Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于上一列的计算列_Sql_Postgresql - Fatal编程技术网

Sql 基于上一列的计算列

Sql 基于上一列的计算列,sql,postgresql,Sql,Postgresql,我们有一张桌子 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'.

我们有一张桌子

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       
.
.
我尝试过使用lag函数,但由于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:计算错误已更正为指出的…

您需要一个:

  • next\u ser
    CTE用于计算下一个序列(如果它们不是真正连续的),借助于从下一个记录中获取值
  • 递归是直接的:非递归部分(UNION的第一个
    SELECT
    语句)是计算第一行的起点。
    联合的第二部分是CTE的递归部分。在此范围内,最后一个递归步骤(
    JOIN cte
    )与具有
    serial
    id的行相连接,该id等于最后一个递归步骤的
    next_serial
    。以前的
    prncpl\u os
    值可以用当前值计算

  • 您还可以分享所需的结果以使其更清晰……以及什么阻止您编写查询?您可能会建议如何获取先前prncpl_os@KaushikNayak的值。您确定第三行的int_金额的值为1180.54吗?96378.4*0.012=1156.5408尽管不需要递归CTE,我认为这是实现逻辑的最简单方法。谢谢,你的答案解决了发布的问题……实际上,表中有一列包含客户端代码。这是一个客户的样本。添加“和a.client_code=c.client_code”以加入cte时,未起作用。我相信我能做到。再次感谢……因此,随着列client_code的添加,它进入了循环关系……上一个序列号的下一个序列号为1(来自下一个客户端代码)。只需要在lead(serial)上放置一个分区,就可以在最后一个serial上获得一个空值。
    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