我有下表:

CREATE TABLE IF NOT EXISTS import.dre
(
    idmov integer,
    companynumber integer,
    idproduct integer,
    dtdate date,
    nrtank integer,
    dailybalance numeric,
    startbalance numeric,
    endbalance numeric
)

填充了以下查询(仅限前10行):

INSERT INTO import.dre values 
(1, 104, 10, '30/09/2023', 5, 0, NULL, 7600),
(2, 104, 10, '01/10/2023', 5,-1089.42, NULL, NULL),
(3, 104, 10, '02/10/2023', 5,-404.62, NULL, NULL),
(4, 104, 10, '03/10/2023', 5,-470.57, NULL, NULL),
(5, 104, 10, '04/10/2023', 5,-604.97, NULL, NULL),
(6, 104, 10, '05/10/2023', 5,10381.23, NULL, NULL),
(7, 104, 10, '06/10/2023', 5,-593.54, NULL, NULL),
(8, 104, 10, '07/10/2023', 5,-713.27, NULL, NULL),
(9, 104, 10, '08/10/2023', 5,-995.01, NULL, NULL),
(10, 104, 10, '09/10/2023', 5,-736.25, NULL, NULL)

我的任务是按照以下模式更新此表: 第一个:startBalance必须是从最后一天开始的联合(endBalance,0),按公司编号、idproduct、nrtank分组.因此,使用这10行,在01/10/2023天,起始余额应该是7600,依此类推.

第二:结束平衡必须是当天的开始平衡加上每日平衡.因此,在这10行,在01/10/2023日结束余额应该是7,600+(-1089.42),以此类推.

最终结果必须如下所示(请原谅,如果这不是您今天看到的最漂亮的数据集,请原谅):

Select * from import.dre:

1, 104, 10, '30/09/2023', 5, 0, NULL, 7600
2, 104, 10, '01/10/2023', 5,-1089.42, 7600, 6510,58 -- 7600-1089.42
3, 104, 10, '02/10/2023', 5,-404.62, 6510,58, 6105,96 -- 6510.58-404.62
4, 104, 10, '03/10/2023', 5,-470.57, 6105.96, 5635,39
5, 104, 10, '04/10/2023', 5,-604.97, 5635,39, 5030,42
6, 104, 10, '05/10/2023', 5,10381.23, 5030,42, 15411,65
7, 104, 10, '06/10/2023', 5,-593.54, 15411,65, 14818,11
8, 104, 10, '07/10/2023', 5,-713.27, 14818,11, 14104,84
9, 104, 10, '08/10/2023', 5,-995.01, 14104,84, 13109,83
10, 104, 10, '09/10/2023', 5,-736.25, 13109,83, 12373,58

有什么办法可以做到这一点吗?我正在try (我知道很糟糕)使用for循环来更新port.dre,但一无所获.如果有比循环更好的方法,我将不胜感激.我不知道Dre能有多重要.

我try 了很多代码,但它们都更新了整个表(而不是计算每一行).我创建的最后一个用于调试的函数如下:

create or replace function teste()
returns void
language plpgsql
as
$$
declare
line record;
v_companynumber int;
v_idproduct int;
v_nrtank int;
v_dtdate date;
v_startbalance numeric;
v_endbalance numeric;
begin
for line in
    select 
        *
    from
        import.dre
    order by
        companynumber, idproduct, nrtank desc, dtdate 
    loop
        v_companynumber := line.companynumber;
        v_idproduct := line.idproduct;
        v_nrtank := line.nrtank;
        v_dtdate := line.dtdate;
        v_startbalance := lag(coalesce(line.endbalance,0), 1) over (
                partition by line.companynumber, line.idproduct, line.nrtank order by line.dtdate);
        v_endbalance := line.endbalance;
        update import.dre
            set startbalance = v_startbalance, endbalance = v_endbalance
        where
            companynumber = v_companynumber
            and idproduct = v_idproduct
            and nrtank = v_nrtank
            and dtdate = v_dtdate;
    end loop;
end;

最后一个查询在startBalance中没有分配任何内容.我试了另一个,但有很多问题要放在这里(我在5号坦克每天得到的最好的一个是7600,但我不记得我是怎么做到的)

推荐答案

你可以先做一个CTE来计算结束平衡,然后在第二步你填好开始平衡.

WITH CTE AS (SELECT idmov, 
                    companynumber,
                    idproduct, 
                    dtdate,
                    nrtank,
                    dailybalance,
                    startbalance,
                    SUM(COALESCE(endbalance,0)+dailybalance)
                       OVER w1 AS endbalance
             FROM import.dre
             WINDOW w1 AS (PARTITION BY companynumber,idproduct,nrtank 
                           ORDER BY dtdate))
SELECT idmov, 
       companynumber,
       idproduct, 
       dtdate,
       nrtank,
       dailybalance,
       LAG(endbalance)OVER w2 AS startbalance,
       endbalance
FROM CTE
WINDOW w2 AS (PARTITION BY companynumber,idproduct,nrtank 
              ORDER BY dtdate);
idmov companynumber idproduct dtdate nrtank dailybalance startbalance endbalance
1 104 10 2023-09-30 5 0 null 7600
2 104 10 2023-10-01 5 -1089.42 7600 6510.58
3 104 10 2023-10-02 5 -404.62 6510.58 6105.96
4 104 10 2023-10-03 5 -470.57 6105.96 5635.39
5 104 10 2023-10-04 5 -604.97 5635.39 5030.42
6 104 10 2023-10-05 5 10381.23 5030.42 15411.65
7 104 10 2023-10-06 5 -593.54 15411.65 14818.11
8 104 10 2023-10-07 5 -713.27 14818.11 14104.84
9 104 10 2023-10-08 5 -995.01 14104.84 13109.83
10 104 10 2023-10-09 5 -736.25 13109.83 12373.58

fiddle

Sql相关问答推荐

如何重用表值用户定义函数调用的结果?

将主表与历史表连接以获取主表的当前汇率以及历史表中的上一个和最后一个汇率

返回包含列和包含其他列的列表的自定义查询

如何根据给定条件PostgreSQL迭代减少组中的行数

找到最新的连线

如何在presto中映射id与名称

根据最大值为字母数字大小写分配数值

在SELECT中将日期格式转换为双周时段

插入具有预期逻辑的查询以Forking 表

按二维数组的第一个元素排序

不同计数的 Postgres PIVOT 表

SQL根据另一列的顺序和值获取组中的最后一列

DB2 SQL查询结果多余数据

在 Oracle 21c 中透视文本值

如何将 START 和 END 日期之间的日期差异作为 SQL 中的单独列获取

如何使用SELECT语句进行左连接,并根据右表中的特定值过滤结果?

SQL中如何转置表格 UNPIVOT是唯一的 Select 吗?

Snowflake中的动态SQL优化

编写查询以根据级别 (p2) 返回父位置

BigQuery 将一行拆分为多列