Может ли рекурсия начинаться с определенной записи в таблице? - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь рассчитать амортизацию по транспортным средствам. Если на транспортное средство есть скидка, мне нужно прекратить амортизацию, рассчитать ее в зависимости от месяца, на который оно влияет, и возобновить расчет амортизации.

Транспортное средство амортизируется по фиксированной ставке 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...