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.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 This shouldnt be this complicated should it?

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: $2
id 2 overpaid by $1. Outstanding: $1
id 3 overpaid by $3. Outstanding: $0
id 4 overpaid by $2. Outstanding: $0
id 5 underpaid by $5. Outstanding: $5
id 6 underpaid by $1. Outstanding: $6
id 7 paid minimum. Outstanding: $6
id 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?
Go to Top of Page

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.
Go to Top of Page

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 INT

SET @id = 1

WHILE 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

END

SELECT *
FROM @solution
Go to Top of Page

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.
Go to Top of Page
   

- Advertisement -