1

I want to achieve the following calculation highlighted in the Desired Output column:

The highlighted row has a running total of 6.4 M, that exceeds the 5M hard limit so the SQL should return the previous row value of 3.64M.

(thus in Excel the formula would be I9=IF(I8+F9 > $H$2, I8, I8+F9)). The same logic should happen for the following rows whenever the Running total breaches the Hard limit.

F G H I
SaleAmount RunningTotal Hard limit Desired output
2 8,778.52 8,778.52 5,000,000 8,778.52
3 1,496,692.06 1,505,470.58 1,505,470.58
4 1,849,601.42 3,355,072 3,355,072
5 445.41 3,355,517.41 3,355,517.41
6 109.98 3,355,627.39 3,355,627.39
7 3,933.56 3,359,560.95 3,359,560.95
8 280,915.44 3,640,476.39 3,640,476.39
9 2,778,827.65 6,419,304.04 3,640,476.39
10 1,349,832.28 7,769,136.32 4,990,308.67
11 2,881.94 7,772,018.26 4,993,190.61
12 145,824.06 7,917,842.32 4,993,190.61
13 316.97 7,918,159.29 4,993,507.58
14 1,181,685.55 9,099,844.84 4,993,507.58
15 2,568.51 9,102,413.35 4,996,076.09
16 3,000 9,105,413.35 4,999,076.09
17 1,286,983.8 1,039,2,397.15 4,999,076.09
18 2,735.87 1,039,5,133.02 4,999,076.09
19 1,442,096.02 1,183,7,229.04 4,999,076.09
  • F. Sale amount
  • G. Running Total : Running total of Sale amount
  • H. Hard Limit : Hard limit when running total exceeds this value the previous row running total should be considered
  • I. ultimate output

How can I achieve this?

3
  • 2
    Please do not upload images of code/data/errors., use a table in your description instead. And show the code that you have tried, so others can show you what to fix instead of having to start from scratch. Commented Jun 3 at 16:12
  • 1
    Please add the appropriate tag for your RDBMS. Commented Jun 3 at 16:27
  • The upvotes on this question do not appear to be merited at all; who on earth felt that this effort-free question was worth rewarding? Commented Jun 9 at 22:23

1 Answer 1

1

Your best bet will be to use a recursive Common Table Expression.

I voluntarily chose the simplest use (row-by-row iterations), because it will be a lot to learn at first,
but you will then be able to optimize it (for example by using a windowed sum() over () to make a first pass containing "everything surely under the cutoff" instead of the row-by-row iterations),
or use RDBMS specific functions (PostgreSQL User-Defined Aggregates).

Here is it with PostgreSQL (you didn't tell which RDBMS you use, so I choose the one I prefer…):

with recursive -- Give each row its position, we'll need it to iterate from row to row: p as (select row_number() over() pos, * from t), -- Now "recurse" (iterate) over rows: r as ( -- Init our recursion with the first amount, use its amount as the first value of the running sum, and as the capped sum if it's less than the cap: select *, amount rs, case when amount > 5000000 then 0 else amount end capped from p where pos = 1 -- Now the recursive part: union all select p.*, rs + p.amount, capped + case when capped + p.amount > 5000000 then 0 else p.amount end -- Use r itself (the previous iteration of our recursive CTE) to have the pos of the last iteration, and fetch the row having the next pos from r join p on p.pos = r.pos + 1 ) select * from r order by pos; 
pos amount rs capped
1 8778.52 8778.52 8778.52
2 1496692.06 1505470.58 1505470.58
3 1849601.42 3355072 3355072
4 445.41 3355517.41 3355517.41
5 109.98 3355627.39 3355627.39
6 3933.56 3359560.95 3359560.95
7 280915.44 3640476.39 3640476.39
8 2778827.65 6419304.04 3640476.39
9 1349832.28 7769136.32 4990308.67
10 2881.94 7772018.260000001 4993190.61
11 145824.06 7917842.32 4993190.61
12 316.97 7918159.29 4993507.58
13 1181685.55 9099844.84 4993507.58
14 2568.51 9102413.35 4996076.09
15 3000 9105413.35 4999076.09
16 1286983.8 10392397.15 4999076.09
17 2735.87 10395133.02 4999076.09
18 1442096.02 11837229.04 4999076.09

I've put it running on your data in an example fiddle you can play with.

Sign up to request clarification or add additional context in comments.

2 Comments

And as I'm in a sufficiently good mood to answer to a question showing no real consideration for potential answerers (as would have a minimal effort shown to understand StackOverflow and a bit of SQL), I may even be kind enough to adapt the fiddle to SQL Server: your Excel background giving good probability that you're in a full -MIcrosoft environment.
Thanks a lot, it worked perfectly ... the RDBMS am using is SQL server, forget to mention that before... But really appreciate your help on this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.