2016-08-31 65 views
0

我需要使用基於表2的正確條目更新表1中的外鍵。正確的外鍵是落在後面的最早日期,但不是之前表2中的下一個生效日期。如果表2中的多個條目具有相同的生效日期,則使用修改的日期列作爲聯絡中斷器並選擇最近的一個。下面是基於表結構(所有時間都是在日期格式):更新表有條件地基於另一個表中的兩列和多行

Table 1 
pK1 PeriodStartDate    pK2  
1  2016-04-01 00:00:00.000    
2  2016-07-01 00:00:00.000 

Table 2 
pK2 EffectiveFrom    ModifiedDate 
3  2016-03-01 00:00:00.000  2016-04-01 00:00:00.000 
4  2016-05-01 00:00:00.000  2016-06-01 00:00:00.000 
5  2016-05-01 00:00:00.000  2016-06-02 00:00:00.000 

所以在上面的示例表1是這樣的:

pK1 PeriodStartDate     pK2  
1  2016-04-01 00:00:00.000   3  
2  2016-07-01 00:00:00.000   5 

這是因爲第1行它屬於之間3月1日和5月1日(來自表2)。第2行是在最後一個日期之後,但由於有兩個類似的開始日期,我們選擇最後一次修改日期。

我不確定解決方案。我是想這樣的事情:

UPDATE table1 
SET pK2 = table2.pK2 
FROM table2 
WHERE PeriodStartDate > (SELECT FIRST(table2.EffectiveFrom) FROM table2) 

我只是不知道如何找到由另一行界的入口(然後需要爲決勝的另一列)

+1

那是怎麼您的數據存儲真的還是是多麼你鍵入了?基於字符串進行日期評估非常麻煩。另外,你有什麼嘗試,請顯示努力。 – JiggsJedi

+0

這就是我爲了便於描述而鍵入的。這兩列都是DateTime。 – CorribView

+0

然後,你需要解決這個問題...並展示你的嘗試。 – JiggsJedi

回答

1

首先,你需要應用而不是Table2,在PeriodStart上進行分區並按ModifiedDate(desc)進行排序。致電MaxModified; 1總是最近修改的記錄。

pK2 PeriodStart    ModifiedDate   MaxModified 
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1 
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1 
4 2016-05-01 00:00:00.000 2016-06-01 00:00:00.000 2 

然後,只在MaxModified=1,你添加一個新的「ID」這個,所以我們可以排隊的開始日期,與下一行的開始日期(我們的結束日期)。這也是由PeriodStart訂購的row_number()函數完成的。

pK2 PeriodStart    ModifiedDate   MaxModified myID 
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1   1 
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1   2 

然後我們把這個結果加入到它自己的偏移一行中,以得到每個原始行的結束日期值。

pK2 PeriodStart    ModifiedDate    MaxModified myID PeriodEnd 
3 2016-03-01 00:00:00.000 2016-04-01 00:00:00.000 1    1  2016-05-01 00:00:00.000 
5 2016-05-01 00:00:00.000 2016-06-02 00:00:00.000 1    2  NULL 

一旦我們有,它的加入對起點的簡單事情/結束日期,讓我們的pk2值。

完整劇本...

DECLARE @Table1 TABLE (pK1 INT, PeriodStart DATETIME, pK2 INT) 
DECLARE @Table2 TABLE (pK2 INT, PeriodStart DATETIME, ModifiedDate DATETIME) 

INSERT INTO @Table1 
VALUES (1,'2016-04-01',NULL), 
     (2,'2016-07-01',NULL) 

INSERT INTO @Table2 
VALUES (3,'2016-03-01','2016-04-01'), 
     (4,'2016-05-01','2016-06-01'), 
     (5,'2016-05-01','2016-06-02') 

;WITH OrderedList AS 
(
    SELECT *, 
      ROW_NUMBER() OVER(PARTITION BY PeriodStart ORDER BY ModifiedDate DESC) AS MaxModified 
    FROM @Table2 
),X AS 
    (
     SELECT *, 
       ROW_NUMBER() OVER(ORDER BY PeriodStart) AS myID 
     FROM OrderedList 
     WHERE MaxModified=1 
    ), Y AS 
     (
      SELECT L.*, R.PeriodStart AS PeriodEnd 
      FROM X L 
      LEFT JOIN X R ON L.myID=R.myID-1 AND R.MaxModified=1 
      WHERE L.MaxModified=1 
     ) 

UPDATE T SET pK2=Y.pK2 
FROM @Table1 T 
LEFT JOIN Y ON T.PeriodStart >= Y.PeriodStart AND T.PeriodStart < COALESCE(Y.PeriodEnd,CURRENT_TIMESTAMP) 

SELECT * 
FROM @Table1 
+0

感謝您花時間幫助我解決這個問題!我剛剛在我的測試數據庫中實現了它。奇怪的是它將表1中的所有pK2列更新爲null。我正在進一步研究。 – CorribView

+0

嘗試刪除更新,並從CTE中選擇:'從y'選擇頂部50 *將是一個好的開始,確保結束開始/結束日期按照邏輯排列。 – JiggsJedi

相關問題