我正在尝试使用某些日期的某些值填充半满的列,其余日期为NULL。
该任务基本填补了前一行值的空白。 它需要n次迭代才能填满整个表格。 我正在使用NUMBERS表进行迭代,它适用于小样本表,如下所示。
当完成18行行数据时,它无法完成查询,因为它会爆炸计算机资源并且运行时无穷无尽。如何扩大规模?
还是有更好的方法吗?这个解决方案起初对我来说似乎很好。
'原样'并且[statusTEST]列如下:
╔════════════╦═══════════╦════════════╦═════════════════╦═════════════════╗
║ SOZLESMENO ║ tDuration ║ YRMONTH ║ statusTest_AsIs ║ statusTest_ToBE ║
╠════════════╬═══════════╬════════════╬═════════════════╬═════════════════╣
║ 40000001 ║ 0 ║ 2010-01-01 ║ 1 ║ 1 ║
║ 40000001 ║ 1 ║ 2010-02-01 ║ NULL ║ 1 ║
║ 40000001 ║ 2 ║ 2010-03-01 ║ NULL ║ 1 ║
║ 40000001 ║ 3 ║ 2010-04-01 ║ NULL ║ 1 ║
║ 40000001 ║ 4 ║ 2010-05-01 ║ 2 ║ 2 ║
║ 40000001 ║ 5 ║ 2010-06-01 ║ NULL ║ 2 ║
║ 40000001 ║ 6 ║ 2010-07-01 ║ NULL ║ 2 ║
║ 40000001 ║ 7 ║ 2010-08-01 ║ NULL ║ 2 ║
║ 40000001 ║ 8 ║ 2010-09-01 ║ 3 ║ 3 ║
║ 40000001 ║ 9 ║ 2010-10-01 ║ NULL ║ 3 ║
║ 40000001 ║ 10 ║ 2010-11-01 ║ NULL ║ 3 ║
╚════════════╩═══════════╩════════════╩═════════════════╩═════════════════╝
我使用以下代码和预定义的10,000行数表
--Numbers table defined
SELECT TOP 10000 H = IDENTITY(INT, 0, 1)
INTO dbo.Numbers
FROM master.dbo.syscolumns a
CROSS JOIN master.dbo.syscolumns b;
--Alternating the table H times to get statusTest_toBE column shown above
DECLARE @iteration_limit INT = 60
UPDATE X
SET X.statusTest = (
CASE
WHEN X.statusTest IS NOT NULL THEN X.statusTest
ELSE Y.statusTest
END
)
FROM
[Mainfiles].dbo.x2Skeleton X
CROSS JOIN [Mainfiles].dbo.Numbers3 N
LEFT JOIN [Mainfiles].dbo.x2Skeleton Y
ON (X.SOZLESMENO = Y.SOZLESMENO)
AND (DATEADD(MONTH, - N.H, X.YRMONTH) = Y.YRMONTH)
AND N.H BETWEEN 1 AND @iteration_limit
答案 0 :(得分:3)
您可以使用窗口功能表达您想要的内容。如果StatusTest_AsIs
总是在增加,您可以使用max()
:
with toupdate as (
select X.*, max(StatusTest_AsIs) over (partition by SOZLESMENO order by YRMONTH) as new_statusTest_ToBE
from [Mainfiles].dbo.x2Skeleton X
)
update toupdate
set statusTest_ToBE = new_statusTest_ToBE
where statusTest_ToBE <> new_statusTest_ToBE;
如果值没有增加,您仍然可以执行此操作。获取先前的非NULL值有点棘手,但APPLY
是一种很好的方法:
with toupdate as (
select X.*, x2.StatusTest_AsIs as new_statusTest_ToBE
from [Mainfiles].dbo.x2Skeleton x cross apply
(select top 1
from [Mainfiles].dbo.x2Skeleton x2
where x2.SOZLESMENO = x.SOZLESMENO and x2.YRMONTH <= YRMONTH and
x2.StatusTest_AsIs is not null
order by YRMONTH desc
) x2
)
update toupdate
set statusTest_ToBE = new_statusTest_ToBE
where statusTest_ToBE <> new_statusTest_ToBE;
对于这两个查询,特别是这个查询,您需要[Mainfiles].dbo.x2Skeleton(SOZLESMENO, YRMONTH, StatusTest_AsIs)
上的索引。