递归可以从表中的特定记录开始吗?

时间:2019-03-27 20:21:44

标签: sql-server

我正在尝试计算车辆的折旧。如果车辆有折扣,我需要停止折旧,根据其影响月份将折价因素考虑在内,然后恢复折旧计算。

车辆每月以2%的固定汇率贬值,其中50个月为100%的贬值点。出现折扣时,我可以停止折旧,但是我不知道如何从某个月开始重新折旧。

下面是在折扣之前直接弃用表的示例:

+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate    | Initial Cost | Monthlydep | totaldep   |
+----------+-------+------------+--------------+------------+------------+
| 12451    | 1     | 2015-08-01 | 44953.24     | 899.06     | 899.0648   |
| 12451    | 2     | 2015-09-01 | 44953.24     | 899.06     | 1798.1296  |
| -------  | ----- | -----      | -----        | -----      | -----      |
| 12451    | 42    | 2019-01-01 | 44953.24     | 899.06     | 37760.7216 |
| 12451    | 43    | 2019-02-01 | 44953.24     | 899.06     | 38659.7864 |
+----------+-------+------------+--------------+------------+------------+

那么,我们假设本月(2019-03-01)会出现返利,然后需要从该月起重新计算折旧。我如何从第43个月开始重新计算折旧,而不是整个过程呢?

例如,假设我们在第44个月获得200美元的返利。该表应如下所示:

+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate    | Initial Cost | Monthlydep | totaldep   |
+----------+-------+------------+--------------+------------+------------+
| 12451    | 43    | 2019-02-01 | 44953.24     | 899.06     | 38659.7864 |
| 12451    | 44    | 2019-03-01 | 44953.24     | 1099.06    | 39758.8464 |
| 12451    | 45    | 2019-04-01 | 44953.24     | 1099.06    | 40857.9064 |
| 12451    | 46    | 2019-05-01 | 44953.24     | 1099.06    | 41956.9664 |
| 12451    | 47    | 2019-06-01 | 44953.24     | 1099.06    | 43056.0264 |
| 12451    | 48    | 2019-06-01 | 44953.24     | 1099.06    | 44155.0864 |
| 12451    | 49    | 2019-06-01 | 44953.24     | 1099.06    | 45254.1464 |
+----------+-------+------------+--------------+------------+------------+

因此,第49个月将是最后一个月份,因为totalDep等于或高于初始费用

我的示例代码如下。如果删除联合的顶部的第一个cte和联接内部联接,则这是工作折旧计算:

;With cte As( Select            bd.[VehicleID]
                ,Max(bd.[Month]) As month
                ,Max(DateAdd(DAY,1,EOMONTH(DepreciationReportDate,-1))) As DepreciationReportDate
                ,Max(bd.MonthlyDepreciation) As MonthlyDepreciation
                ,Max(bd.AdjustedPurchaseCost) As AdjustedPurchaseCost
                ,Max(AccumulatedDepreciation) As AccumulatedDepreciation
            From Work.dbo.DepreciationSchedule bd
            Group By bd.VehicleID
)
,cte_CreateRows As 
        (
            Select bd.[VehicleID]
                ,bd.[Month]
                ,DATEADD(DAY,1,EOMONTH(bd.DepreciationReportDate,-1)) As DepreciationReportDate
                ,bd.MonthlyDepreciation
                ,bd.AdjustedPurchaseCost
                ,bd.AccumulatedDepreciation
            From Work.dbo.DepreciationSchedule bd
            Inner Join cte cte 
            On cte.VehicleID = bd.VehicleID
            And cte.month = bd.Month
            Union All
            Select bd.[VehicleID]
                ,[Month] = Cast(cr.[Month]+1 As int)
                ,DATEADD(DAY,1,EOMONTH(DateAdd(Month, 1, cr.DepreciationReportDate),-1)) As DepreciationReportDate 
                ,bd.MonthlyDepreciation 
                ,bd.AdjustedPurchaseCost
                ,AccumulatedDepreciation = cr.AccumulatedDepreciation + cr.MonthlyDepreciation 
            From Work.dbo.DepreciationSchedule bd
                Inner Join cte_CreateRows cr On bd.[VehicleID] = cr.[VehicleID]
            Where cr.AccumulatedDepreciation < cr.AdjustedPurchaseCost
            And DateAdd(Month,1, DateAdd(DAY,1,EOMONTH(cr.DepreciationReportDate,-1))) < DATEADD(DAY,1,EOMONTH(GetDate(),-1))
        )
Select a.VehicleID
        ,a.Month
        ,a.DepreciationReportDate
        ,Cast(a.MonthlyDepreciation As Decimal(12,2)) As 'Monthly Depreciation Expense'
        ,a.AdjustedPurchaseCost
        ,a.AccumulatedDepreciation
From [cte_CreateRows] As a
Order By a.VehicleID, a.Month

0 个答案:

没有答案