Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
jdaman
Constraint Violating Yak Guru
354 Posts |
Posted - 2010-01-15 : 15:32:54
|
Ok, so Im working on missed payments in a payment cycle and calculating the remaining balance. When a person misses a payment that balance is carried over to the next payment line. If a person pays extra then that overage may be used to settle a past missed payment.Here is some sample data to show my scenario:DECLARE @sample TABLE ( id INT, amt MONEY )INSERT @sample (id, amt) SELECT 1, 2 UNION SELECT 2, -1 UNION SELECT 3, -3 UNION SELECT 4, -2 UNION SELECT 5, 5 UNION SELECT 6, 1 UNION SELECT 7, 0 UNION SELECT 8, 0;/*ids are sequential:id 1 underpaid by $2. Outstanding: $2id 2 overpaid by $1. Outstanding: $1id 3 overpaid by $3. Outstanding: $0id 4 overpaid by $2. Outstanding: $0id 5 underpaid by $5. Outstanding: $5id 6 underpaid by $1. Outstanding: $6id 7 paid minimum. Outstanding: $6id 8 paid minimum. Outstanding: $6*/ Any help would be much appreciated. |
|
|
vijayisonly
Master Smack Fu Yak Hacker
1836 Posts |
Posted - 2010-01-15 : 15:37:43
|
| What is your expected output...and how did you calculate outstanding amount? |
 |
|
|
jdaman
Constraint Violating Yak Guru
354 Posts |
Posted - 2010-01-15 : 15:42:08
|
quote: Originally posted by vijayisonly What is your expected output...and how did you calculate outstanding amount?
Expected outcome would be the outstanding amount listed above.The calculation is line 1s outstanding - line 2s amt. The part that I get caught up on is that I cant carry a negative to the next line. |
 |
|
|
jdaman
Constraint Violating Yak Guru
354 Posts |
Posted - 2010-01-15 : 15:57:23
|
This solution gives me my expected output but there must be a set based way to do this so that Im not having to loop through the whole dataset like this.DECLARE @solution TABLE( id INT, amt MONEY, outstanding MONEY)DECLARE @id INTSET @id = 1WHILE EXISTS ( SELECT 1 FROM @sample WHERE id >= @id ) BEGIN INSERT @solution ( id, amt, outstanding ) SELECT s1.id, s1.amt, CASE WHEN ( s1.amt + ISNULL(s2.outstanding, 0) ) < 0 THEN 0 ELSE s1.amt + ISNULL(s2.outstanding, 0) END FROM @sample s1 LEFT JOIN @solution s2 ON s1.id = s2.id + 1 WHERE s1.id = @id SET @id = @id + 1 ENDSELECT *FROM @solution |
 |
|
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2010-01-16 : 09:21:01
|
| [code]with a as( select id, amt, case when amt > 0 then amt else 0 end as outstanding from @sample where id = 1 union all select s.id, s.amt, case when s.amt + a.outstanding > 0 then s.amt + a.outstanding else 0 end as outstanding from a inner join @sample s on s.id = a.id+1 )select * from a[/code]After I posted this and read it over, I am not too pleased with this solution - for one thing, MAX_RECURSION limits. I have not run this and compared the query plans, but this might be doing the looping just like you are doing. And, it does not look not very elegant etc. So, let us see if someone else will give a better solution. |
 |
|
|
|
|
|
|
|