我有一个如下所示的报告表 - BEFORE:
FREQ_CALC是EFFECTIVEDATE和EXPIRY_DATE之间的月数除以M.之后的noMonths字段FREQ_CODE。
我需要把所有东西都变成这种形状 - 后来。
我想弄清楚如何计算“频率”'以及蓝色,绿色和粉红色的字段(粉红色很容易)。基本上,' FREQ_CODE'有一个' M'性格,然后在一个月内我有几个月和几天。如果noMonths是3,我需要用90开始mxDays,然后找到maturityDate字段的天数差异,因此它不是两个字段之间的DATEDIFF(),而是日期增加之间的DATEDIFF相同的字段,按Credit_Line_NO分组。因此,黄色的三个单元格开始mxDays。此外,当mxDays为30或90时,mxFactor为1,当mxDays为365时,mxFactor为365/360。最后,Calc为mxDays * Amount。这非常容易。我无法弄清楚如何设置mxDays和mxFactor。有人可以帮我解决这个问题吗?
为了更加清晰,91天= 6/30/2018 - 3/31/2018和92天= 9/30/2018 - 6/30/2018。此外,1.0111 = 91/90和1.0222 = 92/90。同样,0.8111 = 73/90。最后,1.0139 = 365/360因为noMonths = 12。
也许这需要一个CTE和一对案例...当......然后陈述。不确定......
我正在使用SQL Server 2008。
-- Here is my DDL
-- Drop table Reporting_Table
CREATE TABLE Reporting_Table (
Credit_Line_NO Varchar(10),
noMonths INT,
EFFECTIVEDATE Date,
EXPIRY_DATE Date,
Amount Money,
mxDays INT,
mxFactor decimal(5,4),
Calc Money)
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('9938810','3','3/31/2018','6/12/2020','11718.75','90','1','11718.75')
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('2235461','1','6/30/2018','6/6/2019','12345','30','1','12345')
INSERT INTO Reporting_Table (Credit_Line_NO, noMonths, EFFECTIVEDATE, EXPIRY_DATE, Amount, mxDays, mxFactor, Calc)
Values('3365434','12','6/30/2018','6/30/2019','298523.36085','365','1.01388888888889','302669.518639583')
答案 0 :(得分:2)
对于SQL 2008,您需要使用row_number
订购表,并将每行加入前一行。然后进行计算
with cte as (
select
*, rn = row_number() over (partition by Credit_Line_NO order by maturityDate)
from
Reporting_Table
)
select
a.*, mxDay = isnull(q.dayDiff, q.mDay), z.mxFactor
, Calc = z.mxFactor * a.Amount
from
cte a
left join cte b on a.Credit_Line_NO = b.Credit_Line_NO and a.rn - 1 = b.rn
cross apply (select
mDay = case
when a.noMonths = 1 then 30
when a.noMonths = 3 then 90
when a.noMonths = 12 then 365
end, dayDiff = datediff(dd, b.maturityDate, a.maturityDate)) q
cross apply (select mxFactor = cast(1.0 * isnull(q.dayDiff, q.mDay) / q.mDay as decimal(10,4))) z
编辑: 这是更新查询:
with cte as (
select
*, rn = row_number() over (partition by Credit_Line_NO order by maturityDate)
from
Reporting_Table
)
, cte2 as (
select
a.Credit_Line_NO, a.noMonths, a.maturityDate, a.Amount, mxDay = isnull(q.dayDiff, q.mDay), z.mxFactor
, Calc = z.mxFactor * a.Amount
from
cte a
left join cte b on a.Credit_Line_NO = b.Credit_Line_NO and a.rn - 1 = b.rn
cross apply (select
mDay = case
when a.noMonths = 1 then 30
when a.noMonths = 3 then 90
when a.noMonths = 12 then 365
end, dayDiff = datediff(dd, b.maturityDate, a.maturityDate)) q
cross apply (select mxFactor = cast(1.0 * isnull(q.dayDiff, q.mDay) / q.mDay as decimal(10,4))) z
)
update r
set r.mxDay = c.mxDay, r.mxFactor = c.mxFactor, r.Calc = c.Calc
from
Reporting_Table r
join cte2 c on r.Credit_Line_NO = c.Credit_Line_NO and r.noMonths = c.noMonths and r.maturityDate = c.maturityDate