2017-10-10 65 views
0

我试图推导年金支付计划。我知道网上有一些解决方案,但由于我需要对每月付款金额进行更改,因此我无法使用这些解决方案,并且由于安全策略,我无法安装新的软件包。现在我很难计算每月期初余额,因为它取决于最后一行计算的资本。有没有一种更有效的方式来做到这一点,然后光标。我现在有三千万行。TSQL 2012中光标的高效替代以获取付款计划计算的最后值

数据我:

这是一个很简单的例子,可以有不同的价格,不同的每月付款和日期失踪。所以我无法在线使用可用的解决方案。

enter image description here

最终的结果我想:

其中:

  • 利息=期初余额X费
  • 资本=每月还款 - 利息
  • 期初余额=上一次开幕余额 - 上次注册费用

enter image description here

我曾尝试使用LAG,但它不工作作为LAG是一个确定性的功能。

这里是帐户数据的脚本。

CREATE TABLE [temp_da_test].[example_3](
    [Account] [nvarchar](255) NULL, 
    [Month] [date] NULL, 
    [Rate Charge] [float] NULL, 
    [Opening Balance] [money] NULL, 
    [Monthly Repayment] [money] NULL, 
    [Interest] [money] NULL, 
    [Capital] [money] NULL 
) ON [PRIMARY] 

GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-06-30' AS Date), 0.014419, 2000.0000, 0.0000, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-07-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-08-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-09-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-10-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-11-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2005-12-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-01-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-02-28' AS Date), 0.013458, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-03-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-04-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-05-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-06-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-07-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-08-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-09-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-10-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-11-30' AS Date), 0.014419, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2006-12-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'A', CAST(N'2007-01-31' AS Date), 0.0149, NULL, 35.8800, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-06-30' AS Date), 0.014419, 4000.0000, 0.0000, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-07-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-08-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-09-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-10-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-11-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2005-12-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-01-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-02-28' AS Date), 0.013458, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-03-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-04-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-05-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-06-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-07-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-08-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-09-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-10-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-11-30' AS Date), 0.014419, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2006-12-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 
INSERT [temp_da_test].[example_3] ([Account], [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital]) VALUES (N'B', CAST(N'2007-01-31' AS Date), 0.0149, NULL, 71.7600, NULL, NULL) 
GO 

回答

1

因为你的利率是不相符的,你不能因此使用interest rate calculation,你不会得到任何比再逐行更有效率。

虽然不是最大的性能,明智的,你会看到一个更高效的执行利用递归Common Table ExpressionCTE),即join s到自身,并检查派生表中的一行与下一个进来的,它在你的大小写是下一个月你需要计算的值。

因为该行已经全面存在CTE内,你可以象引用的计算值在cursor

declare @t table(Account nvarchar(5),[Month] date null,[Rate Charge] float null,[Opening Balance] money null,[Monthly Repayment] money null); 
insert into @t (Account, [Month], [Rate Charge], [Opening Balance], [Monthly Repayment]) values 
(N'A', CAST(N'2005-06-30' AS Date), 0.014419, 2000.0000, 0.0000),(N'A', CAST(N'2005-07-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2005-08-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2005-09-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2005-10-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2005-11-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2005-12-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-01-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-02-28' AS Date), 0.013458, NULL, 35.8800),(N'A', CAST(N'2006-03-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-04-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2006-05-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-06-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2006-07-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-08-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-09-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2006-10-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2006-11-30' AS Date), 0.014419, NULL, 35.8800),(N'A', CAST(N'2006-12-31' AS Date), 0.0149, NULL, 35.8800),(N'A', CAST(N'2007-01-31' AS Date), 0.0149, NULL, 35.8800) 
,(N'B', CAST(N'2005-06-30' AS Date), 0.014419, 4000.0000, 0.0000),(N'B', CAST(N'2005-07-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2005-08-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2005-09-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2005-10-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2005-11-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2005-12-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-01-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-02-28' AS Date), 0.013458, NULL, 71.7600),(N'B', CAST(N'2006-03-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-04-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2006-05-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-06-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2006-07-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-08-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-09-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2006-10-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2006-11-30' AS Date), 0.014419, NULL, 71.7600),(N'B', CAST(N'2006-12-31' AS Date), 0.0149, NULL, 71.7600),(N'B', CAST(N'2007-01-31' AS Date), 0.0149, NULL, 71.7600) 
; 

with d as 
(
    select Account 
      ,[Month] 
      ,[Rate Charge] 
      ,[Opening Balance] 
      ,[Monthly Repayment] 
      ,row_number() over (order by Account,[Month]) as rn 
    from @t 
) 
,c as 
(
    -- Start with just the first row from your source data: 
    select top 1 Account 
       ,[Month] 
       ,[Rate Charge] 
       ,cast([Opening Balance] as decimal(12,2)) as [Opening Balance] 
       ,[Monthly Repayment] 
       ,[Opening Balance] * [Rate Charge] as Interest 
       ,[Monthly Repayment] - ([Opening Balance] * [Rate Charge]) as Capital 
       ,rn 
    from d 
    order by [Month] 

    union all -- Then add on the next row until the end of the dataset is reached: 

    select d.Account 
      ,d.[Month] 
      ,d.[Rate Charge] 
      ,case when c.Account <> d.Account  -- When we hit a new account, restart the calculations: 
       then cast(d.[Opening Balance] as decimal(12,2)) 
       else cast(c.[Opening Balance] - c.Capital as decimal(12,2)) 
       end as [Opening Balance] 
      ,d.[Monthly Repayment] 
      ,case when c.Account <> d.Account 
       then d.[Opening Balance] * d.[Rate Charge] 
       else (c.[Opening Balance] - c.Capital) * d.[Rate Charge] 
       end as Interest 
      ,case when c.Account <> d.Account 
       then d.[Monthly Repayment] - (d.[Opening Balance] * d.[Rate Charge]) 
       else d.[Monthly Repayment] - ((c.[Opening Balance] - c.Capital) * d.[Rate Charge]) 
       end as Capital 
      ,d.rn 
    from c 
     join d 
      on c.rn = d.rn-1 
) 
select Account 
     ,[Month] 
     ,[Rate Charge] 
     ,[Opening Balance] 
     ,[Monthly Repayment] 
     ,Interest 
     ,Capital 
from c 
order by rn 
option (maxrecursion 0) -- No matter how big the dataset is. 

输出:

+---------+------------+-------------+-----------------+-------------------+------------------+------------------+ 
| Account | Month | Rate Charge | Opening Balance | Monthly Repayment |  Interest  |  Capital  | 
+---------+------------+-------------+-----------------+-------------------+------------------+------------------+ 
| A  | 2005-06-30 | 0.014419 |   2000.00 |    0.00 |   28.838 |   -28.838 | 
| A  | 2005-07-31 |  0.0149 |   2028.84 |    35.88 |  30.2296862 |  5.6503138 | 
| A  | 2005-08-31 |  0.0149 |   2023.19 |    35.88 | 30.14552632438 | 5.73447367562001 | 
| A  | 2005-09-30 | 0.014419 |   2017.46 |    35.88 | 29.0896912340712 | 6.79030876592877 | 
| A  | 2005-10-31 |  0.0149 |   2010.67 |    35.88 | 29.9589783993877 | 5.92102160061234 | 
| A  | 2005-11-30 | 0.014419 |   2004.75 |    35.88 | 28.9064755195408 | 6.97352448045923 | 
| A  | 2005-12-31 |  0.0149 |   1997.78 |    35.88 | 29.7668694852412 | 6.11313051475884 | 
| A  | 2006-01-31 |  0.0149 |   1991.67 |    35.88 | 29.6758363553301 | 6.20416364466991 | 
| A  | 2006-02-28 | 0.013458 |   1985.47 |    35.88 | 26.72039922567 | 9.15960077432997 | 
| A  | 2006-03-31 |  0.0149 |   1976.31 |    35.88 | 29.4470249484625 | 6.43297505153752 | 
| A  | 2006-04-30 | 0.014419 |   1969.88 |    35.88 | 28.4036568227319 | 7.47634317726812 | 
| A  | 2006-05-31 |  0.0149 |   1962.40 |    35.88 | 29.2398144866587 | 6.64018551334129 | 
| A  | 2006-06-30 | 0.014419 |   1955.76 |    35.88 | 28.2001007650831 | 7.67989923491687 | 
| A  | 2006-07-31 |  0.0149 |   1948.08 |    35.88 | 29.0263935013997 | 6.85360649860026 | 
| A  | 2006-08-31 |  0.0149 |   1941.23 |    35.88 | 28.9242732631709 | 6.95572673682915 | 
| A  | 2006-09-30 | 0.014419 |   1934.27 |    35.88 | 27.8903007461817 | 7.98969925381834 | 
| A  | 2006-10-31 |  0.0149 |   1926.28 |    35.88 | 28.7015764811181 | 7.1784235188819 | 
| A  | 2006-11-30 | 0.014419 |   1919.10 |    35.88 | 27.6715256312812 | 8.20847436871876 | 
| A  | 2006-12-31 |  0.0149 |   1910.89 |    35.88 | 28.4722837319061 | 7.40771626809391 | 
| A  | 2007-01-31 |  0.0149 |   1903.48 |    35.88 | 28.3618860276054 | 7.5181139723946 | 
| B  | 2005-06-30 | 0.014419 |   4000.00 |    0.00 |   57.676 |   -57.676 | 
| B  | 2005-07-31 |  0.0149 |   4057.68 |    71.76 |  60.4593724 |  11.3006276 | 
| B  | 2005-08-31 |  0.0149 |   4046.38 |    71.76 | 60.29105264876 | 11.46894735124 | 
| B  | 2005-09-30 | 0.014419 |   4034.91 |    71.76 | 58.1793824681425 | 13.5806175318575 | 
| B  | 2005-10-31 |  0.0149 |   4021.33 |    71.76 | 59.9178077987753 | 11.8421922012247 | 
| B  | 2005-11-30 | 0.014419 |   4009.49 |    71.76 | 57.8128047006505 | 13.9471952993495 | 
| B  | 2005-12-31 |  0.0149 |   3995.54 |    71.76 | 59.5335877900397 | 12.2264122099603 | 
| B  | 2006-01-31 |  0.0149 |   3983.31 |    71.76 | 59.3513724580716 | 12.4086275419284 | 
| B  | 2006-02-28 | 0.013458 |   3970.90 |    71.76 | 53.4403906705407 | 18.3196093294593 | 
| B  | 2006-03-31 |  0.0149 |   3952.58 |    71.76 | 58.8934478209911 | 12.8665521790089 | 
| B  | 2006-04-30 | 0.014419 |   3939.71 |    71.76 | 56.8067282041309 | 14.9532717958691 | 
| B  | 2006-05-31 |  0.0149 |   3924.76 |    71.76 | 58.4788752502416 | 13.2811247497585 | 
| B  | 2006-06-30 | 0.014419 |   3911.48 |    71.76 | 56.3996139022332 | 15.3603860977668 | 
| B  | 2006-07-31 |  0.0149 |   3896.12 |    71.76 | 58.0521822471433 | 13.7078177528567 | 
| B  | 2006-08-31 |  0.0149 |   3882.41 |    71.76 | 57.8479415154824 | 13.9120584845176 | 
| B  | 2006-09-30 | 0.014419 |   3868.50 |    71.76 | 55.7798718187117 | 15.9801281812883 | 
| B  | 2006-10-31 |  0.0149 |   3852.52 |    71.76 | 57.4025460900988 | 14.3574539099012 | 
| B  | 2006-11-30 | 0.014419 |   3838.16 |    71.76 | 55.3424657520731 | 16.4175342479269 | 
| B  | 2006-12-31 |  0.0149 |   3821.74 |    71.76 | 56.9439627397059 | 14.8160372602941 | 
| B  | 2007-01-31 |  0.0149 |   3806.92 |    71.76 | 56.7231670448216 | 15.0368329551784 | 
+---------+------------+-------------+-----------------+-------------------+------------------+------------------+ 
+0

@imdave是CTE更好的条件的表现?因为我觉得我会更多地用光标控制。此外,我有多个帐户,因此查询的第一部分将无法工作,并且是顶部1 –

+0

游标在几乎所有情况下都会有最差的表现。如果您更新样本数据以包含多个帐户,则可以对其进行修改以处理那些没有太多问题的人员。 – iamdave

+0

@AamirKhan我已经更新了我的脚本,以便按不同的“账户”分割计算。 – iamdave

1

你可以使用CTE来尝试这样的事情。
在CTE构造中,它使用ROW_NUMBER将每一行与前一行相链接,并按照您所描述的计算各种数量。

WITH X AS (SELECT [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Monthly Repayment]-[Opening Balance]* [Rate Charge] AS [Capital] 
         , ROW_NUMBER() OVER (ORDER BY [Month]) AS RN 
       FROM [example_2]           
       ) 
    , X2 AS (SELECT [Month] 
        , [Rate Charge] 
        , [Opening Balance] 
        , [Monthly Repayment] 
        , [Interest]=[Opening Balance]*[Rate Charge] 
        , [Capital] 
        , RN 
       FROM X WHERE RN=1 
       UNION ALL 
       SELECT X.[Month] 
        , X.[Rate Charge] 
        , CAST(XX1.[Opening Balance]-XX1.Capital AS money) AS [Opening Balance] 
        , X.[Monthly Repayment] 
        , (XX1.[Opening Balance]-XX1.Capital)*X.[Rate Charge] AS [Interest] 
         , X.[Monthly Repayment]-(XX1.[Opening Balance]-XX1.Capital)*X.[Rate Charge] AS [Capital] 
        , X.RN    
       FROM X 
       INNER JOIN X2 XX1 ON X.RN=XX1.RN+1 
       ) 
    SELECT [Month], [Rate Charge], [Opening Balance], [Monthly Repayment], [Interest], [Capital] 
    FROM X2; 

输出:

Month  Rate Charge   Opening Balance  Monthly Repayment  Interest    Capital 
---------- ---------------------- --------------------- --------------------- ---------------------- ---------------------- 
2005-06-30 0.014419    2000.00    0.00     28.838     -28.838 
2005-07-31 0.0149     2028.838    35.88     30.2296862    5.6503138 
2005-08-31 0.0149     2023.1877    35.88     30.14549652438   5.73450347562 
2005-09-30 0.014419    2017.4532    35.88     29.089657640685  6.79034235931497 
2005-10-31 0.0149     2010.6629    35.88     29.9588765788462  5.9211234211538 
2005-11-30 0.014419    2004.7418    35.88     28.9063716764904  6.97362832350962 
2005-12-31 0.0149     1997.7682    35.88     29.7667457579797  6.1132542420203 
2006-01-31 0.0149     1991.6549    35.88     29.6756586917939  6.2043413082061 
2006-02-28 0.013458    1985.4506    35.88     26.7201936188742  9.15980638112584 
2006-03-31 0.0149     1976.2908    35.88     29.4467328249212  6.43326717507878 
2006-04-30 0.014419    1969.8575    35.88     28.4033757658025  7.47662423419746 
2006-05-31 0.0149     1962.3809    35.88     29.2394750489105  6.64052495108955 
2006-06-30 0.014419    1955.7404    35.88     28.1998204678302  7.68017953216976 
2006-07-31 0.0149     1948.0602    35.88     29.0260972849707  6.85390271502934 
2006-08-31 0.0149     1941.2063    35.88     28.9239738295461  6.95602617045394 
2006-09-30 0.014419    1934.2503    35.88     27.8899546983482  7.99004530165178 
2006-10-31 0.0149     1926.2603    35.88     28.7012777950054  7.17872220499462 
2006-11-30 0.014419    1919.0816    35.88     27.6712372702262  8.20876272977382 
2006-12-31 0.0149     1910.8728    35.88     28.4720052753264  7.40799472467363 
2007-01-31 0.0149     1903.4648    35.88     28.3616255986024  7.51837440139764