IF OBJECT_ID('tempdb..#ReflectionRatio') IS NOT NULL DROP TABLE #ReflectionRatio
CREATE TABLE #ReflectionRatio(
[ReflectionRatioKey] [int] IDENTITY(1,1) NOT NULL,
[StartDate] [date] NULL,
[ProvinceNo] [nvarchar](3) NULL,
[Rate] [float] NULL,
[Period] [nvarchar](10) NULL
)
INSERT INTO #ReflectionRatio VALUES
(1,'2005-01-01','712',0.0002,'2005-01'),
(2,'2005-01-01','750',0.0661,'2005-01'),
(3,'2019-06-01','712',0.000114,'2019-06'),
(4,'2019-06-01','750',0.05972,'2019-06'),
(5,'2020-05-31','712',0.0002,'2020-05'),
(6,'2020-05-01','750',0.0661,'2020-05'),
(7,'2023-05-02','712',0.000242,'2023-05'),
(8,'2023-05-02','750',0.069265,'2023-05')
我需要根据下面定义的规则填写缺失值: 填写日期期间 : 2005-01-01 / 2023-12-31
-- 规则 1:如果特定省份缺少比率,则取上一个最近的比率:
例如:对于 750 个省份,从 2019-07 期间到 2020-05,记录应为:
(IDENTITYCOLUMN,'2019-07-01','750',0.05972,'2019-07'),
(IDENTITYCOLUMN,'2019-08-01','750',0.05972,'2019-08'),
(IDENTITYCOLUMN,'2019-09-01','750',0.05972,'2019-09'),
........
........
(IDENTITYCOLUMN,'2020-04-01','750',0.05972,'2020-04')
--规则2:一个省内所有比率值都为0.0,则取之前所有省份的比率。
注:其实我有很多省份,不只是712和750!
我尝试使用窗口函数(LEAD 和 LAG)来解决它,但我只设法获取第一个下一条记录和上一条记录。
ProvinceNo-750 以及从 2019-07 期间到 2023-12,记录应为:
(IDENTITYCOLUMN,'2019-07-01','750',0.05972,'2019-07'),
(IDENTITYCOLUMN,'2019-08-01','750',0.05972,'2019-08'),
(IDENTITYCOLUMN,'2019-09-01','750',0.05972,'2019-09'),
........
........
(IDENTITYCOLUMN,'2020-04-01','750',0.05972,'2020-04')
(IDENTITYCOLUMN,'2020-05-01','750',0.0661,'2020-05')
(IDENTITYCOLUMN,'2020-06-01','750',0.0661,'2020-06')
.........
.........
(IDENTITYCOLUMN,'2023-04-01','750',0.0661,'2023-04')
(IDENTITYCOLUMN,'2023-05-02','750',0.069265,'2023-05')
(IDENTITYCOLUMN,'2023-06-02','750',0.069265,'2023-06')
.........
.........
(IDENTITYCOLUMN,'2023-12-02','750',0.069265,'2023-12')
我感谢任何帮助,谢谢!
下面的解决方案是使用
tally
表。使用 lead()
获取下一个 StartDate
并找出月份的差异即可得出缺失的行数。将其加入到 tally
表 (numbers
) 中,您将获得缺失的行。
对于条件
ratio with 0.0
,只需将其视为缺失行并从cte中排除它ReflectionRatio
with condition
where r.Rate <> 0
对于这种情况,您需要对表执行更新而不是插入。
with ReflectionRatio as
(
select ProvinceNo, StartDate,
NextDate = lead(StartDate) over (partition by r.ProvinceNo order by r.StartDate),
Rate
from #ReflectionRatio r
)
select r.ProvinceNo,
StartDate = dateadd(month, n, r.StartDate),
r.Rate
from ReflectionRatio r
inner join numbers n on n.n >= 1
and n.n < datediff(month, r.StartDate, r.NextDate)