我正在努力构建两个计算列(名为balance
和avg
)。
name seq side price qnt
groupA 1 B 30 100
groupA 2 B 36 200
groupA 3 S 23 300
groupA 4 B 30 100
groupA 5 B 54 400
groupB 1 B 70 300
groupB 2 B 84 300
groupB 3 B 74 600
groupB 4 S 90 100
2个新计算列的依据:
余额:每组的第一行(seq = 1)必须具有相同的值qnt
。接下来的记录遵循以下公式(基于Excel的方案):
if(side="B"; `previous balance record` + `qnt`; `previous balance record` - `qnt`)
avg:每组的第一行(seq = 1)必须具有相同的值price
。接下来的记录遵循以下公式(基于Excel的方案):
if(side="B"; ((`price` \* `qnt`) + (`previous balance record` \* `previous avg record`)) / (`qnt` + `previous balance record`); `previous avg record`)
数字示例(A组的第二行计算如下):
--> balance: 100 + 200 = 300
--> avg: ((36 * 200) + (100 * 30)) / (200 + 100) = 34
我认为这个问题必须用CTE来解决,因为我需要以前的记录,每次都在计算中。
我不想聚合组-我的目标是显示每个记录。
最后,这是我期望的输出:
name seq side price qnt balance avg
groupA 1 B 30 100 100 30
groupA 2 B 36 200 300 34
groupA 3 S 23 300 0 34
groupA 4 B 30 100 100 30
groupA 5 B 54 400 500 49,2
groupB 1 B 70 300 300 70
groupB 2 B 84 300 600 77
groupB 3 B 74 600 1200 75,5
groupB 4 S 90 100 1100 75,5
提前感谢您!
下面是我的dbfiddle测试:https://dbfiddle.uk/TSarc3Nl
我试着解释了部分编码(注解)以使事情更容易。
1条答案
按热度按时间fruv7luv1#
余额可以从累计和中导出(使用case表达式表示何时扣除而不是添加)。
然后递归部分只需要一个自己的case表达式。
https://dbfiddle.uk/mWz945pG
虽然我不确定avg是要做什么,所以有可能我弄错了,或者它可能被简化为不需要递归。
注意:***切勿***使用
,
连接表。***EDIT:***无递归版本
使用窗口函数来累计余额以及总支出。
然后,使用该函数启用另一个窗口函数,以累计销售“收回”了多少“支出”。
您的平均值是调整后的支出除以当前余额。
https://dbfiddle.uk/O0HEr556
注:我仍然不明白为什么你要用这种方式计算平均价格,但它符合你想要的结果/公式,没有递归。