如何基于同一数据库中的输入来计算新列

时间:2018-09-18 19:07:47

标签: sql-server

我有几个客户的贷款组合,每个客户都可以用下表格式显示。

DATE        DPD    DPD_BUCK    DATE_REST    RESTRUCTURED    REST_PERIOD
2017-03-01  90       90+       NULL             NO           NULL
2017-04-01  90       90+       NULL             NO           NULL
2017-05-01  2        0-29      2017-04-10       YES           1
2017-06-01  0         0        2017-04-10       YES           2
2017-07-01  0         0        2017-04-10       YES           3
2017-08-01  0         0        2017-04-10       YES           4
2017-09-01  0         0        2017-04-10       YES           5
2017-10-01  20       0-29      2017-04-10       YES           6
2017-11-01  51      30-59      2017-04-10       YES           7
2017-12-01  82      60-89      2017-04-10       YES           8
2018-01-01  90       90+       2017-04-10       YES           9
2018-02-01  90       90+       2017-04-10       YES          10
2018-03-01  90       90+       2017-04-10       YES          11
2018-04-01  90       90+       2017-04-10       YES          12

列名

DPD = Number of overdue days on payments             
DPD_BUCK = Risk bucket  
DATE_REST = Date of restructuring of the loan   
REST_PERIOD = Number of months since last restructuring

我需要添加一个新列(DPD_UPD),该列将根据是否使用以下逻辑对贷款进行重组来调整原始DPD值:

CASE
WHEN REST_PERIOD = 1 or REST_PERIOD = 2 THEN DPD (value 1 month before restructuring)
WHEN REST_PERIOD = 3 AND DPD = 0 THEN DPD (value from the previous period less 29 days)
WHEN REST_PERIOD = 3 AND DPD <> 0 THEN DPD (value from the previous period plus 29 days)
WHEN REST_PERIOD = 4 AND DPD = 0 THEN DPD (value from the previous period less 29 days)    
WHEN REST_PERIOD = 4 AND DPD <> 0 THEN (value from the previous period plus 29 days)
.
.
.

依此类推,直到周期12,DPD不能小于0或大于90。

预期结果应如下所示:

DATE        DPD    DPD_UPD   DPD_BUCK      DATE_REST    RESTRUCTURED    REST_PERIOD
2017-03-01  90       90         90+            NULL             NO           NULL
2017-04-01  90       90         90+            NULL             NO           NULL
2017-05-01  2        90         0-29       2017-04-10          YES            1
2017-06-01  0        90          0         2017-04-10          YES            2
2017-07-01  0        61          0         2017-04-10          YES            3
2017-08-01  0        32          0         2017-04-10          YES            4
2017-09-01  0        3           0         2017-04-10          YES            5  
2017-10-01  20       32         0-29       2017-04-10          YES            6
2017-11-01  51       61        30-59       2017-04-10          YES            7
2017-12-01  82       90        60-89       2017-04-10          YES            8
2018-01-01  90       90         90+        2017-04-10          YES            9
2018-02-01  90       90         90+        2017-04-10          YES           10
2018-03-01  90       90         90+        2017-04-10          YES           11
2018-04-01  90       90         90+        2017-04-10          YES           12

如果有人可以提供帮助,我将非常感谢。 提前谢谢

1 个答案:

答案 0 :(得分:0)

我使用了递归CTE:

with
  r as (
    select top 1 DPD DPD_UPD, * from @lp order by [DATE]
      union all
    select
      case l.RESTRUCTURED
        when 'NO' then l.DPD
        else
          case
            when l.REST_PERIOD < 3 then
              coalesce((select DPD
                        from @lp i
                        where dateadd(mm,
                                datediff(mm, 0, l.DATE_REST) - 1,
                                0) = i.[DATE]), r.DPD_UPD)
            else
              iif(l.DPD = 0,
                  iif(r.DPD_UPD - 29 < 0, 0, r.DPD_UPD - 29),
                  iif(r.DPD_UPD + 29 > 90, 90, r.DPD_UPD + 29))
          end
      end,
      l.*
    from r join @lp l on dateadd(mm, 1, r.[DATE]) = l.[DATE]
  )
select * from r order by [DATE];

Here可以测试我的尝试。
但是就性能而言,使用游标的解决方案更为可取。