2017-01-02 133 views
0

我需要使用基于ID & DATE列的最后一个已知值中的新值更新NULL值。请注意,只要ID列正在更改,非空值更新应该会更改。与SQL Server中其他表中的属性相关的属性

下面的例子查询,Null由5 L2取代& 2016年1月12日行,但作为ID被改变为L2和5从L1行把它应为空。但每当ID正在改变时,我需要获得R_ID

我的表有9000万行,更新过程应尽可能快。

CREATE TABLE #temp 
(
    ID nvarchar(10), 
    DATE date, 
    R_ID INT 
); 

INSERT INTO #temp 
    SELECT 'L1', '2016-12-01', NULL 
    UNION ALL 
    SELECT 'L1', '2016-12-02', 5 
    UNION ALL 
    SELECT 'L1', '2016-12-03', NULL 
    UNION ALL 
    SELECT 'L2', '2016-12-01', NULL 
    UNION ALL 
    SELECT 'L2', '2016-12-02', 8 
    UNION ALL 
    SELECT 'L2', '2016-12-03', NULL 
    UNION ALL 
    SELECT 'L3', '2016-12-03', 3 
    UNION ALL 
    SELECT 'L3', '2016-12-04', NULL 
    UNION ALL 
    SELECT 'L3', '2016-12-04', NULL ; 

DECLARE @R_ID INT; 

UPDATE #temp WITH(TABLOCKX) 
SET @R_ID = R_ID = CASE WHEN R_ID IS NULL THEN @R_ID ELSE R_ID END 
OPTION(MAXDOP 1); 

enter image description here

回答

0

一种方法是在内部查询使用的更新语句:

UPDATE t1 
SET R_ID = ISNULL(R_ID, (
         SELECT TOP 1 R_ID 
         FROM #Temp t2 
         WHERE t2.ID = t1.Id 
         AND T2.[DATE] < t1.[DATE] 
         AND t2.R_ID IS NOT NULL 
         ORDER BY [DATE] DESC) 
       ) 
FROM #Temp t1 

测试更新:

SELECT * 
FROM #Temp 

结果:

ID DATE     R_ID 
L1 01.12.2016 00:00:00  NULL 
L1 02.12.2016 00:00:00  5 
L1 03.12.2016 00:00:00  5 
L2 01.12.2016 00:00:00  NULL 
L2 02.12.2016 00:00:00  8 
L2 03.12.2016 00:00:00  8 
L3 03.12.2016 00:00:00  3 
L3 04.12.2016 00:00:00  3 
L3 04.12.2016 00:00:00  3 
+0

逻辑正在工作,但查询需要一个多小时才能更新90 m记录。 – Rajini

+0

那么,如果90米涉及90,000,000条记录,那么对于使用子查询进行更新的时间并不长...... –