【发布时间】:2020-10-26 00:19:03
【问题描述】:
我有下表,我正在尝试为其计算运行余额和剩余值,但剩余值是先前计算的行的函数,如下所示:
date PR amount total balance remaining_value
----------------------------------------------------------
'2020-1-1' 1 1.0 100.0 1.0 100 -- 100 (inital total)
'2020-1-2' 1 2.0 220.0 3.0 320 -- 100 (previous row) + 220
'2020-1-3' 1 -1.5 -172.5 1.5 160 -- 320 - 160 (see explanation 1)
'2020-1-4' 1 3.0 270.0 4.5 430 -- 160 + 270
'2020-1-5' 1 1.0 85.0 5.5 515 -- 430 + 85
'2020-1-6' 1 2.0 202.0 7.5 717 -- 575 + 202
'2020-1-7' 1 -4.0 -463.0 3.5 334.6 -- 717 - 382.4 (see explanation 2)
'2020-1-8' 1 -0.5 -55.0 3.0 ...
'2020-1-9' 1 2.0 214.0 5.0
'2020-1-1' 2 1.0 100 1.0 100 -- different PR: start new running total
逻辑如下:
-
对于正数行,剩余值只是
remaining_value列中前一行的值 + 该行total列中的值。 -
对于负数行,它会变得更复杂:
解释 1: 我们从320(前一行余额)开始,从中删除1.5/3.0(当前行金额的绝对值除以前一行余额),然后乘以上一行remaining_value,即320。计算得出:
320 - (1.5/3 * 320) = 160
解释2:逻辑同上。 717 - (4/7.5 * 717) = 717 - 382.4
4/7.5这里表示当前行的绝对金额除以上一行的余额。
我尝试了窗口函数sum(),但没有得到想要的结果。有没有办法在 PostgreSQL 中完成这项工作而不必求助于循环?
额外的复杂性:有多个产品由 PR(产品 ID)、1、2 等标识。每个产品都需要自己的运行总计和计算。
【问题讨论】:
-
我使用了一个日期字段来对它们进行排序,但出于本示例的目的,我只显示了排序表。你知道了,当总数为正时,我们只需将它们相加,当总数为负时,我们使用前一个总数的公式(因此忽略负数)。我要补充一点,PR 字段代表产品 ID,并且可能有多个产品 ID。通常,我会用窗口函数和分区将它们分开,但在这种情况下不知道该怎么做..
标签: sql postgresql aggregate-functions window-functions cumulative-sum