如何在同一字段中找到记录的DATEDIFF?

时间:2018-02-09 23:33:07

标签: sql sql-server tsql

我有一个如下所示的报告表 - BEFORE:

enter image description here

FREQ_CALC是EFFECTIVEDATE和EXPIRY_DATE之间的月数除以M.之后的noMonths字段FREQ_CODE。

enter image description here

我需要把所有东西都变成这种形状 - 后来。

enter image description here

我想弄清楚如何计算“频率”'以及蓝色,绿色和粉红色的字段(粉红色很容易)。基本上,' 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') 

1 个答案:

答案 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