I must apply a certain transformation fn(argument)
. Here argument
is equal to value
, but not when it is negative. When you get a first negative value
, then you "wait" until it sums up with consecutive values and this sum becomes positive. Then you do fn(argument)
. See the table I want to get:
value argument --------------------- 2 2 3 3 -10 0 4 0 3 0 10 7 1 1
I could have summed all values and apply fn
to the sum, but fn
can be different for different rows and it is essential to know the row number to choose a concrete fn.
As want a Postgres SQL solution, looks like window functions fit, but I am not experienced enough to write expression that does that yet. In fact, I am new to "thinking in sql", unfortunately. I guess that can be easily done in an imperative way, but I do not want to write a stored procedure yet.
This doesn't really fit any of the predefined aggregation functions. You probably need to write your own. Note that in postgresql, aggregate functions can be used as window functions, and in fact that is the only way to write window functions in anything other than C, as of 9.0.
You can write a function that tracks the state of "summing" the values, except that it always returns the input value if the current "sum" is positive, and just keeps adding when the "sum" is negative. Then you simply need to take the greater of either this sum or zero. To whit:
You need to create an aggregate function to invoke this accumulator:
This defines that the aggregate takes integers as input and stores its state as an integer.
I copied your example into a table:
And you can now have those values produced by using the aggregate function with a window clause:
So as you can see, the final step is that you need to take the output of the function if it is positive, or zero. This can be done by wrapping the query, or writing a function to do that:
and now:
This produces the arguments for the function that you specified in the question.
I suppose I'm late, but this may help someone: