Sql 如何查找同一字段中记录的DATEDIFF?
我有一个报告表,如下所示-之前: FREQ_CALC是生效日期和到期日期之间的月数,除以M后的noMonths字段FREQ_CODE 我需要把所有的东西都做成这个样子——之后 我试图找出如何计算“频率”以及蓝色、绿色和粉色的字段(粉红色非常简单)。基本上,“FREQ_CODE”有一个“M”字符,在这之后,我一个月有几个月和几天。如果noMonths是3,我需要以90开始mxDays,然后从到期日期字段中找出天数的差异,因此这不是两个字段之间的DATEDIFF(),而是同一字段中增加日期之间的DATEDIFF,按信用额度编号分组。因此,黄色的三个单元格开始mxDays。此外,当mxDays为30或90时,mxFactor为1;当mxDays为365时,mxFactor为365/360。最后,Calc是mxDays*金额。这非常简单。我只是不知道如何获得mxDays和mxFactor设置 为进一步明确起见,91天=2018年6月30日-2018年3月31日,92天=2018年9月30日-2018年6月30日。同样,1.0111=91/90和1.0222=92/90。同样,0.8111=73/90。最后,1.0139=365/360,因为noMonths=12 也许这需要一个CTE和几个案例…当…然后陈述。不确定 我正在使用SQLServer2008Sql 如何查找同一字段中记录的DATEDIFF?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个报告表,如下所示-之前: FREQ_CALC是生效日期和到期日期之间的月数,除以M后的noMonths字段FREQ_CODE 我需要把所有的东西都做成这个样子——之后 我试图找出如何计算“频率”以及蓝色、绿色和粉色的字段(粉红色非常简单)。基本上,“FREQ_CODE”有一个“M”字符,在这之后,我一个月有几个月和几天。如果noMonths是3,我需要以90开始mxDays,然后从到期日期字段中找出天数的差异,因此这不是两个字段之间的DATEDIFF(),而是同一字段中增加日期之间
-- 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')
对于SQL 2008,您需要使用
行数
对表进行排序,并将每一行与前一行连接起来。然后进行计算
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
对,对,对!!这应该够了!非常感谢!你知道,感觉自己对某些技术相当了解,然后意识到自己不知道如何做一些看起来相当简单的事情,然后看到其他人解决问题的方法,这是一种谦卑。此外,看到SQL的强大功能也非常令人惊讶。再次感谢,没问题!我们都在那里:)你好。我试图获得CTE的结果,以更新数据所在的原始基表。我该怎么做?我想应该是:更新报告表集合mxDay=z.mxDay mxFactor=z.mxFactor,Calc=z.Calc这些都不起作用。我做错了什么?Uzi,我在周五晚上晚些时候发布问题时犯了一个错误。我想我整个星期都在工作,太累了。我实际上没有给我一个频率场;我需要计算这个,然后在屏幕截图中更新before表,使其看起来像after表。我确信这在基本SQL中是可能的,我认为交叉应用程序可以做到这一点,但我似乎无法让它正常工作。你知道怎么解决这个烂摊子吗?我必须使用此CTE进行更新;我不能只运行Select查询。SQL具有与excel相同的功能,您可以通过以下方式计算频率:
天花(1.0*datediff(mm,EFFECTIVEDATE,expiration\u DATE)/noMonths)