I have the following data, composed of the A
value, ordered by MM
(month).
The B
column is computed as GREATEST(current value of A + previous value of B, 0)
in a spreadsheet-like fashion.
How can I compute B
using a SQL Query?
- I tried using Analytic Functions, but I was unable to succeed.
- I know there is the Model Clause; I found a similar example, but I don't know where to begin.
I am using Oracle 10g, therefore I cannot use recursive queries.
Here is my test data:
MM | A | B
-----------+--------+------
2012-01-01 | 800 | 800
2012-02-01 | 1900 | 2700
2012-03-01 | 1750 | 4450
2012-04-01 | -20000 | 0
2012-05-01 | 900 | 900
2012-06-01 | 3900 | 4800
2012-07-01 | -2600 | 2200
2012-08-01 | -2600 | 0
2012-09-01 | 2100 | 2100
2012-10-01 | -2400 | 0
2012-11-01 | 1100 | 1100
2012-12-01 | 1300 | 2400
And here is the "table definition":
select t.* from (
select date'2012-01-01' as mm, 800 as a from dual union all
select date'2012-02-01' as mm, 1900 as a from dual union all
select date'2012-03-01' as mm, 1750 as a from dual union all
select date'2012-04-01' as mm, -20000 as a from dual union all
select date'2012-05-01' as mm, 900 as a from dual union all
select date'2012-06-01' as mm, 3900 as a from dual union all
select date'2012-07-01' as mm, -2600 as a from dual union all
select date'2012-08-01' as mm, -2600 as a from dual union all
select date'2012-09-01' as mm, 2100 as a from dual union all
select date'2012-10-01' as mm, -2400 as a from dual union all
select date'2012-11-01' as mm, 1100 as a from dual union all
select date'2012-12-01' as mm, 1300 as a from dual
) t;
Sorry if this is off topic, given the Oracle version of the question, but we can now use the SQL:2016 MATCH_RECOGNIZE clause:
It does however not produce this line:
because it calculates 900 - 20000 in that row, and zero is bigger than the result of that. You can "fix" that if you use the
abs
function to get rid of the negative value in the computation.So let's unleash the
MODEL
clause (a device whose mystery is only exceeded by its power) on this problem:The above yields:
I came up with a user-defined aggregate function
Here is the query