How to make this Cursor work better
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I have a table and I am trying to apply payments to the loan amounts. Payments must be applied to initial loan until it is zero before going to next loan.
First I must say cursors are not my strong point but I gave it a try. I cannot get the cursor to apply the pmnt_amt
from the DEAL_FP_CALC_BEG_BAL_AMT
until it gets to zero and apply any remaining payments to the next DEAL_FP_CALC_BEG_BAL_AMT
.
For example a DEAL_FP_CALC_BEG_BAL_AMT
of 5000 will be paid down like this:
5000.00- 1235.3 = 3764.7
3764.7 - 1122.00 = 2642.7
2642.7 - 1035.3 = 1607.4
1607.4 - 1005.4 = 602.00
602.4 -1005.2 = (403.2) Loan paid off
(403.2) + 7500 - 1235.3(next payment) = 5861.5 until this is paid
Table is
FP_MERCH_ID PMNT_SEQ_ID PMNT_AMT PMNT_DT DEAL_FP_BAL_AMT FUND_DT
2359 1122 1235.3 10/1/15 5000 9/1/15
2359 1123 1122 10/12/15 5000 9/1/15
2359 1124 1035.3 10/19/15 5000 9/1/15
2359 1125 1005.4 10/24/15 5000 9/1/15
2359 1126 1105.2 10/29/15 5000 9/1/15
2359 1127 1235.3 11/3/15 7500 10/31/15
2359 1128 1122 11/8/15 7500 10/31/15
2359 1129 1035.3 11/13/15 7500 10/31/15
2359 1130 1005.4 11/18/15 7500 10/31/15
2359 1131 1105.2 11/23/15 7500 10/31/15
Here is my code below.
DEAL_FP_CALC_BEG_BAL_AMT
is loan amount.
--DECLARE @COUNTER INT
DECLARE @PAYMENT INT
DECLARE @BALANCE INT
--DECLARE @MAXCOUNT INT
DECLARE @RESULTS INT
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW where FP_MERCH_ID = 2359
)
DECLARE VINTAGE CURSOR
FOR SELECT PMNT_AMT From LOOPDATA_NEW Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT
OPEN VINTAGE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @PAYMENT
/* begin
set @RESULTS = @BALANCE - @PAYMENT
end */
PRINT @BALANCE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
END
CLOSE VINTAGE
DEALLOCATE VINTAGE
sql-server sql-server-2008 t-sql cursors
bumped to the homepage by Community♦ 17 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I have a table and I am trying to apply payments to the loan amounts. Payments must be applied to initial loan until it is zero before going to next loan.
First I must say cursors are not my strong point but I gave it a try. I cannot get the cursor to apply the pmnt_amt
from the DEAL_FP_CALC_BEG_BAL_AMT
until it gets to zero and apply any remaining payments to the next DEAL_FP_CALC_BEG_BAL_AMT
.
For example a DEAL_FP_CALC_BEG_BAL_AMT
of 5000 will be paid down like this:
5000.00- 1235.3 = 3764.7
3764.7 - 1122.00 = 2642.7
2642.7 - 1035.3 = 1607.4
1607.4 - 1005.4 = 602.00
602.4 -1005.2 = (403.2) Loan paid off
(403.2) + 7500 - 1235.3(next payment) = 5861.5 until this is paid
Table is
FP_MERCH_ID PMNT_SEQ_ID PMNT_AMT PMNT_DT DEAL_FP_BAL_AMT FUND_DT
2359 1122 1235.3 10/1/15 5000 9/1/15
2359 1123 1122 10/12/15 5000 9/1/15
2359 1124 1035.3 10/19/15 5000 9/1/15
2359 1125 1005.4 10/24/15 5000 9/1/15
2359 1126 1105.2 10/29/15 5000 9/1/15
2359 1127 1235.3 11/3/15 7500 10/31/15
2359 1128 1122 11/8/15 7500 10/31/15
2359 1129 1035.3 11/13/15 7500 10/31/15
2359 1130 1005.4 11/18/15 7500 10/31/15
2359 1131 1105.2 11/23/15 7500 10/31/15
Here is my code below.
DEAL_FP_CALC_BEG_BAL_AMT
is loan amount.
--DECLARE @COUNTER INT
DECLARE @PAYMENT INT
DECLARE @BALANCE INT
--DECLARE @MAXCOUNT INT
DECLARE @RESULTS INT
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW where FP_MERCH_ID = 2359
)
DECLARE VINTAGE CURSOR
FOR SELECT PMNT_AMT From LOOPDATA_NEW Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT
OPEN VINTAGE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @PAYMENT
/* begin
set @RESULTS = @BALANCE - @PAYMENT
end */
PRINT @BALANCE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
END
CLOSE VINTAGE
DEALLOCATE VINTAGE
sql-server sql-server-2008 t-sql cursors
bumped to the homepage by Community♦ 17 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
I have a table and I am trying to apply payments to the loan amounts. Payments must be applied to initial loan until it is zero before going to next loan.
First I must say cursors are not my strong point but I gave it a try. I cannot get the cursor to apply the pmnt_amt
from the DEAL_FP_CALC_BEG_BAL_AMT
until it gets to zero and apply any remaining payments to the next DEAL_FP_CALC_BEG_BAL_AMT
.
For example a DEAL_FP_CALC_BEG_BAL_AMT
of 5000 will be paid down like this:
5000.00- 1235.3 = 3764.7
3764.7 - 1122.00 = 2642.7
2642.7 - 1035.3 = 1607.4
1607.4 - 1005.4 = 602.00
602.4 -1005.2 = (403.2) Loan paid off
(403.2) + 7500 - 1235.3(next payment) = 5861.5 until this is paid
Table is
FP_MERCH_ID PMNT_SEQ_ID PMNT_AMT PMNT_DT DEAL_FP_BAL_AMT FUND_DT
2359 1122 1235.3 10/1/15 5000 9/1/15
2359 1123 1122 10/12/15 5000 9/1/15
2359 1124 1035.3 10/19/15 5000 9/1/15
2359 1125 1005.4 10/24/15 5000 9/1/15
2359 1126 1105.2 10/29/15 5000 9/1/15
2359 1127 1235.3 11/3/15 7500 10/31/15
2359 1128 1122 11/8/15 7500 10/31/15
2359 1129 1035.3 11/13/15 7500 10/31/15
2359 1130 1005.4 11/18/15 7500 10/31/15
2359 1131 1105.2 11/23/15 7500 10/31/15
Here is my code below.
DEAL_FP_CALC_BEG_BAL_AMT
is loan amount.
--DECLARE @COUNTER INT
DECLARE @PAYMENT INT
DECLARE @BALANCE INT
--DECLARE @MAXCOUNT INT
DECLARE @RESULTS INT
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW where FP_MERCH_ID = 2359
)
DECLARE VINTAGE CURSOR
FOR SELECT PMNT_AMT From LOOPDATA_NEW Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT
OPEN VINTAGE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @PAYMENT
/* begin
set @RESULTS = @BALANCE - @PAYMENT
end */
PRINT @BALANCE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
END
CLOSE VINTAGE
DEALLOCATE VINTAGE
sql-server sql-server-2008 t-sql cursors
I have a table and I am trying to apply payments to the loan amounts. Payments must be applied to initial loan until it is zero before going to next loan.
First I must say cursors are not my strong point but I gave it a try. I cannot get the cursor to apply the pmnt_amt
from the DEAL_FP_CALC_BEG_BAL_AMT
until it gets to zero and apply any remaining payments to the next DEAL_FP_CALC_BEG_BAL_AMT
.
For example a DEAL_FP_CALC_BEG_BAL_AMT
of 5000 will be paid down like this:
5000.00- 1235.3 = 3764.7
3764.7 - 1122.00 = 2642.7
2642.7 - 1035.3 = 1607.4
1607.4 - 1005.4 = 602.00
602.4 -1005.2 = (403.2) Loan paid off
(403.2) + 7500 - 1235.3(next payment) = 5861.5 until this is paid
Table is
FP_MERCH_ID PMNT_SEQ_ID PMNT_AMT PMNT_DT DEAL_FP_BAL_AMT FUND_DT
2359 1122 1235.3 10/1/15 5000 9/1/15
2359 1123 1122 10/12/15 5000 9/1/15
2359 1124 1035.3 10/19/15 5000 9/1/15
2359 1125 1005.4 10/24/15 5000 9/1/15
2359 1126 1105.2 10/29/15 5000 9/1/15
2359 1127 1235.3 11/3/15 7500 10/31/15
2359 1128 1122 11/8/15 7500 10/31/15
2359 1129 1035.3 11/13/15 7500 10/31/15
2359 1130 1005.4 11/18/15 7500 10/31/15
2359 1131 1105.2 11/23/15 7500 10/31/15
Here is my code below.
DEAL_FP_CALC_BEG_BAL_AMT
is loan amount.
--DECLARE @COUNTER INT
DECLARE @PAYMENT INT
DECLARE @BALANCE INT
--DECLARE @MAXCOUNT INT
DECLARE @RESULTS INT
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW where FP_MERCH_ID = 2359
)
DECLARE VINTAGE CURSOR
FOR SELECT PMNT_AMT From LOOPDATA_NEW Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT
OPEN VINTAGE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @PAYMENT
/* begin
set @RESULTS = @BALANCE - @PAYMENT
end */
PRINT @BALANCE
FETCH NEXT FROM VINTAGE INTO @PAYMENT
END
CLOSE VINTAGE
DEALLOCATE VINTAGE
sql-server sql-server-2008 t-sql cursors
sql-server sql-server-2008 t-sql cursors
edited Aug 19 '16 at 23:22
Andriy M
16.3k63473
16.3k63473
asked Aug 17 '16 at 11:26
CJackCJack
214
214
bumped to the homepage by Community♦ 17 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 17 mins ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You never actually reduce your balance here. I think you mean to do this:
SET @BALANCE = @FP_CALC_BEG_BAL_AMT;
OPEN VINTAGE;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @BALANCE - @PAYMENT;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
END
CLOSE VINTAGE;
DEALLOCATE VINTAGE;
In this example, you set your starting balance to the initial loan amount. Then on each iteration of the cursor you reduce the balance by the payment amount.
I'm not sure why you chose to use a cursor, I am sure you have your reasons, but would the below not achieve the desired result without using one?
DECLARE @TOTAL_PAYMENTS INT;
SET @TOTAL_PAYMENTS = (SELECT SUM(PMNT_AMT)
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @TOTAL_PAYMENTS;
Also, in your code you are casting your balance and payments to INT
, this loses the decimal precision which could cause you to lose money if this were to be a real-world example. Remember to use an accurate data type such as DECIMAL
so that you capture these values correctly.
EDIT BASED ON COMMENT
The reason you only every return the largest loan is because of this line in your code:
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
You only ever fetch the largest loan here. If you want to loop through each loan and then each payment you can do this:
DECLARE @loan DECIMAL(9,2) = 0;
DECLARE @balance DECIMAL(9,2) = 0;
DECLARE @payment DECIMAL(9,2) = 0;
DECLARE loans CURSOR
FOR (SELECT DISTINCT DEAL_FP_CALC_BEG_BAL_AMT
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
OPEN loans;
FETCH NEXT FROM loans INTO @loan;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @balance = @balance + @loan;
DECLARE payments CURSOR
FOR (SELECT PMNT_AMT
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
OPEN payments;
FETCH NEXT FROM payments INTO @payment;
WHILE @@FETCH_STATUS = 0 AND @balance > 0
BEGIN
SET @balance = @balance - @payment;
FETCH NEXT FROM payments INTO @payment;
END
CLOSE payments;
DEALLOCATE payments;
FETCH NEXT FROM loans INTO @loan;
END
CLOSE loans;
DEALLOCATE loans;
PRINT @balance;
Aaron Bertrand gives a fantastic answer on the different methods you can use to calculate running totals for this question. I highly recommend checking it out as I feel it will help you in the long run.
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f147049%2fhow-to-make-this-cursor-work-better%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You never actually reduce your balance here. I think you mean to do this:
SET @BALANCE = @FP_CALC_BEG_BAL_AMT;
OPEN VINTAGE;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @BALANCE - @PAYMENT;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
END
CLOSE VINTAGE;
DEALLOCATE VINTAGE;
In this example, you set your starting balance to the initial loan amount. Then on each iteration of the cursor you reduce the balance by the payment amount.
I'm not sure why you chose to use a cursor, I am sure you have your reasons, but would the below not achieve the desired result without using one?
DECLARE @TOTAL_PAYMENTS INT;
SET @TOTAL_PAYMENTS = (SELECT SUM(PMNT_AMT)
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @TOTAL_PAYMENTS;
Also, in your code you are casting your balance and payments to INT
, this loses the decimal precision which could cause you to lose money if this were to be a real-world example. Remember to use an accurate data type such as DECIMAL
so that you capture these values correctly.
EDIT BASED ON COMMENT
The reason you only every return the largest loan is because of this line in your code:
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
You only ever fetch the largest loan here. If you want to loop through each loan and then each payment you can do this:
DECLARE @loan DECIMAL(9,2) = 0;
DECLARE @balance DECIMAL(9,2) = 0;
DECLARE @payment DECIMAL(9,2) = 0;
DECLARE loans CURSOR
FOR (SELECT DISTINCT DEAL_FP_CALC_BEG_BAL_AMT
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
OPEN loans;
FETCH NEXT FROM loans INTO @loan;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @balance = @balance + @loan;
DECLARE payments CURSOR
FOR (SELECT PMNT_AMT
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
OPEN payments;
FETCH NEXT FROM payments INTO @payment;
WHILE @@FETCH_STATUS = 0 AND @balance > 0
BEGIN
SET @balance = @balance - @payment;
FETCH NEXT FROM payments INTO @payment;
END
CLOSE payments;
DEALLOCATE payments;
FETCH NEXT FROM loans INTO @loan;
END
CLOSE loans;
DEALLOCATE loans;
PRINT @balance;
Aaron Bertrand gives a fantastic answer on the different methods you can use to calculate running totals for this question. I highly recommend checking it out as I feel it will help you in the long run.
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
add a comment |
You never actually reduce your balance here. I think you mean to do this:
SET @BALANCE = @FP_CALC_BEG_BAL_AMT;
OPEN VINTAGE;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @BALANCE - @PAYMENT;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
END
CLOSE VINTAGE;
DEALLOCATE VINTAGE;
In this example, you set your starting balance to the initial loan amount. Then on each iteration of the cursor you reduce the balance by the payment amount.
I'm not sure why you chose to use a cursor, I am sure you have your reasons, but would the below not achieve the desired result without using one?
DECLARE @TOTAL_PAYMENTS INT;
SET @TOTAL_PAYMENTS = (SELECT SUM(PMNT_AMT)
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @TOTAL_PAYMENTS;
Also, in your code you are casting your balance and payments to INT
, this loses the decimal precision which could cause you to lose money if this were to be a real-world example. Remember to use an accurate data type such as DECIMAL
so that you capture these values correctly.
EDIT BASED ON COMMENT
The reason you only every return the largest loan is because of this line in your code:
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
You only ever fetch the largest loan here. If you want to loop through each loan and then each payment you can do this:
DECLARE @loan DECIMAL(9,2) = 0;
DECLARE @balance DECIMAL(9,2) = 0;
DECLARE @payment DECIMAL(9,2) = 0;
DECLARE loans CURSOR
FOR (SELECT DISTINCT DEAL_FP_CALC_BEG_BAL_AMT
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
OPEN loans;
FETCH NEXT FROM loans INTO @loan;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @balance = @balance + @loan;
DECLARE payments CURSOR
FOR (SELECT PMNT_AMT
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
OPEN payments;
FETCH NEXT FROM payments INTO @payment;
WHILE @@FETCH_STATUS = 0 AND @balance > 0
BEGIN
SET @balance = @balance - @payment;
FETCH NEXT FROM payments INTO @payment;
END
CLOSE payments;
DEALLOCATE payments;
FETCH NEXT FROM loans INTO @loan;
END
CLOSE loans;
DEALLOCATE loans;
PRINT @balance;
Aaron Bertrand gives a fantastic answer on the different methods you can use to calculate running totals for this question. I highly recommend checking it out as I feel it will help you in the long run.
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
add a comment |
You never actually reduce your balance here. I think you mean to do this:
SET @BALANCE = @FP_CALC_BEG_BAL_AMT;
OPEN VINTAGE;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @BALANCE - @PAYMENT;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
END
CLOSE VINTAGE;
DEALLOCATE VINTAGE;
In this example, you set your starting balance to the initial loan amount. Then on each iteration of the cursor you reduce the balance by the payment amount.
I'm not sure why you chose to use a cursor, I am sure you have your reasons, but would the below not achieve the desired result without using one?
DECLARE @TOTAL_PAYMENTS INT;
SET @TOTAL_PAYMENTS = (SELECT SUM(PMNT_AMT)
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @TOTAL_PAYMENTS;
Also, in your code you are casting your balance and payments to INT
, this loses the decimal precision which could cause you to lose money if this were to be a real-world example. Remember to use an accurate data type such as DECIMAL
so that you capture these values correctly.
EDIT BASED ON COMMENT
The reason you only every return the largest loan is because of this line in your code:
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
You only ever fetch the largest loan here. If you want to loop through each loan and then each payment you can do this:
DECLARE @loan DECIMAL(9,2) = 0;
DECLARE @balance DECIMAL(9,2) = 0;
DECLARE @payment DECIMAL(9,2) = 0;
DECLARE loans CURSOR
FOR (SELECT DISTINCT DEAL_FP_CALC_BEG_BAL_AMT
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
OPEN loans;
FETCH NEXT FROM loans INTO @loan;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @balance = @balance + @loan;
DECLARE payments CURSOR
FOR (SELECT PMNT_AMT
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
OPEN payments;
FETCH NEXT FROM payments INTO @payment;
WHILE @@FETCH_STATUS = 0 AND @balance > 0
BEGIN
SET @balance = @balance - @payment;
FETCH NEXT FROM payments INTO @payment;
END
CLOSE payments;
DEALLOCATE payments;
FETCH NEXT FROM loans INTO @loan;
END
CLOSE loans;
DEALLOCATE loans;
PRINT @balance;
Aaron Bertrand gives a fantastic answer on the different methods you can use to calculate running totals for this question. I highly recommend checking it out as I feel it will help you in the long run.
You never actually reduce your balance here. I think you mean to do this:
SET @BALANCE = @FP_CALC_BEG_BAL_AMT;
OPEN VINTAGE;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @BALANCE = @BALANCE - @PAYMENT;
FETCH NEXT FROM VINTAGE INTO @PAYMENT;
END
CLOSE VINTAGE;
DEALLOCATE VINTAGE;
In this example, you set your starting balance to the initial loan amount. Then on each iteration of the cursor you reduce the balance by the payment amount.
I'm not sure why you chose to use a cursor, I am sure you have your reasons, but would the below not achieve the desired result without using one?
DECLARE @TOTAL_PAYMENTS INT;
SET @TOTAL_PAYMENTS = (SELECT SUM(PMNT_AMT)
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
SET @BALANCE = @FP_CALC_BEG_BAL_AMT - @TOTAL_PAYMENTS;
Also, in your code you are casting your balance and payments to INT
, this loses the decimal precision which could cause you to lose money if this were to be a real-world example. Remember to use an accurate data type such as DECIMAL
so that you capture these values correctly.
EDIT BASED ON COMMENT
The reason you only every return the largest loan is because of this line in your code:
DECLARE @FP_CALC_BEG_BAL_AMT INT
SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT)
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
You only ever fetch the largest loan here. If you want to loop through each loan and then each payment you can do this:
DECLARE @loan DECIMAL(9,2) = 0;
DECLARE @balance DECIMAL(9,2) = 0;
DECLARE @payment DECIMAL(9,2) = 0;
DECLARE loans CURSOR
FOR (SELECT DISTINCT DEAL_FP_CALC_BEG_BAL_AMT
From LOOPDATA_NEW
where FP_MERCH_ID = 2359);
OPEN loans;
FETCH NEXT FROM loans INTO @loan;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @balance = @balance + @loan;
DECLARE payments CURSOR
FOR (SELECT PMNT_AMT
From LOOPDATA_NEW
Where FP_MERCH_ID = 2359
Group by FP_MERCH_ID, PMNT_SEQ_ID, PMNT_AMT);
OPEN payments;
FETCH NEXT FROM payments INTO @payment;
WHILE @@FETCH_STATUS = 0 AND @balance > 0
BEGIN
SET @balance = @balance - @payment;
FETCH NEXT FROM payments INTO @payment;
END
CLOSE payments;
DEALLOCATE payments;
FETCH NEXT FROM loans INTO @loan;
END
CLOSE loans;
DEALLOCATE loans;
PRINT @balance;
Aaron Bertrand gives a fantastic answer on the different methods you can use to calculate running totals for this question. I highly recommend checking it out as I feel it will help you in the long run.
edited May 23 '17 at 12:40
Community♦
1
1
answered Aug 18 '16 at 5:06
Mr.BrownstoneMr.Brownstone
9,80732342
9,80732342
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
add a comment |
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
You code works for largest loan amt but I need it to go to the next loan amt after the first is paid off. I also cannot use "SET @FP_CALC_BEG_BAL_AMT = (SELECT MAX(DEAL_FP_CALC_BEG_BAL_AMT) From LOOPDATA_NEW where FP_MERCH_ID = 2359 )"
– CJack
Aug 19 '16 at 13:04
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
Updated my answer.
– Mr.Brownstone
Aug 19 '16 at 21:45
add a comment |
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f147049%2fhow-to-make-this-cursor-work-better%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown