Eva*_*oll 3 postgresql aggregate window-functions running-totals
这是一个非常有趣的问题(针对 SQL Server 提出的问题),我想尝试一下,看看它是如何在 PostgreSQL 中完成的。让我们看看其他人是否可以做得更好。拿着这个数据,
CREATE TABLE foo
AS
SELECT pkid::int, numvalue::int, groupid::int
FROM ( VALUES
( 1, -1 , 1 ),
( 2, -2 , 1 ),
( 3, 5 , 1 ),
( 4, -7 , 1 ),
( 5, 1 , 2 )
) AS t(pkid, numvalue, groupid);
Run Code Online (Sandbox Code Playgroud)
我们正在尝试生成这个:
PKID RollingSum GroupID
----------------------------- ## Explanation:
1 0 1 ## 0 - 1 < 0 => 0
2 0 1 ## 0 - 2 < 0 => 0
3 5 1 ## 0 + 5 > 0 => 5
4 0 1 ## 5 - 7 < 0 => 0
Run Code Online (Sandbox Code Playgroud)
问题描述为,
当添加一个负数将导致总和为负时,将激活限制以将结果设置为零。后续的加法应该基于这个调整后的值,而不是原来的滚动总和。
应该使用加法来达到预期的结果。如果第四个数字从 -7 变为 -3,则第四个结果应该是 2 而不是 0
如果可以提供单个金额而不是几个滚动数字,那也是可以接受的。我可以使用存储过程来实现非负加法,但这太低级了。
现实生活中的问题是我们将下订单记录为正数,取消订单为负数。由于连接问题,客户可能
cancel
会多次单击该按钮,这将导致记录多个负值。在计算我们的收入时,“零”需要作为销售额的界限。
他们的解决方案都是使用递归。
dno*_*eth 10
这就是我使用嵌套 OLAP 函数在 Teradata 上解决类似问题的方法:
SELECT dt.*,
-- find the lowest previous CumSum < 0
-- and adjust the current CumSum to zero
Max(CASE WHEN CumSum < 0 THEN -CumSum ELSE 0 end)
Over (PARTITION BY groupid
ORDER BY pkid
ROWS Unbounded Preceding)
+ CumSum AS AdjustedSum
FROM
(
SELECT pkid, numvalue, groupid,
-- calculate a standard cumulative sum
Sum(numvalue)
Over (PARTITION BY groupid
ORDER BY pkid
ROWS Unbounded Preceding) AS CumSum
FROM foo
) AS dt
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4522 次 |
最近记录: |