How to make this Cursor work better





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







1















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









share|improve this question
















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.






















    1















    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









    share|improve this question
















    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.


















      1












      1








      1


      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









      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      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.
























          1 Answer
          1






          active

          oldest

          votes


















          0














          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.






          share|improve this answer


























          • 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












          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
          });


          }
          });














          draft saved

          draft discarded


















          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









          0














          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.






          share|improve this answer


























          • 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
















          0














          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.






          share|improve this answer


























          • 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














          0












          0








          0







          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.






          share|improve this answer















          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          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



















          • 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


















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Liste der Baudenkmale in Friedland (Mecklenburg)

          Single-Malt-Whisky

          Czorneboh