2010-05-19 71 views
0

使用MS SQL 2005中的1-1關係,使用SQL兩個表中有相互

表1

ID | T1Value | T2ID | GroupID 
---------------------------------- 
1 |  a  | 10 |  1 
2 |  b  | 11 |  1 
3 |  c  | 12 |  1 
4 |  a  | 22 |  2 

表2

ID | T2Value 
---------------- 
10 |  H 
11 |  J 
12 |  K 
22 |  H 

我想克隆數據將GroupID == 1的數據克隆到新的GroupID中,以便得出以下結果:

表1

ID | T1Value | T2ID | GroupID 
---------------------------------- 
1 |  a  | 10 |  1 
2 |  b  | 11 |  1 
3 |  c  | 12 |  1 
4 |  a  | 22 |  2 
5 |  a  | 23 |  3 
6 |  b  | 24 |  3 
7 |  c  | 25 |  3 

表2

ID | T2Value 
---------------- 
10 |  H 
11 |  J 
12 |  K 
22 |  H 
23 |  H 
24 |  J 
25 |  K 

,我發現了一些SQL克隆模式,讓我克隆在同一個表數據好...但我開始處理兩個表中的數據克隆同時,然後正確地連接新的行......這不是我覺得我有一個很好的把握。

我想我可以做一些自我連接來處理這個問題,但是我擔心非關鍵字段在多行中具有相同數據的情況。

+1

爲什麼表2在第二步之後只有7條記錄?似乎應該有8? – 2010-05-19 18:42:04

+0

@Abe - 這兩個表應該有相同的記錄數,因爲它們鏈接到1-1。你爲什麼認爲他們應該8?我不認爲我可以忽略任何東西,但是在編寫SQL頁面之後,我的腦海裏充滿了煩惱。 – AmoebaMan17 2010-05-19 18:52:19

+0

順便說一句 - 請注意表1中的GroupID列。我只想克隆屬於同一GroupID的記錄。因此,我的示例僅克隆GroupID 1中的記錄。 – AmoebaMan17 2010-05-19 18:54:18

回答

1

我唯一的選擇是使用遊標來跟蹤ID映射嗎?這是我寫的一些僞代碼...還沒有測試過。我希望有更簡潔的東西。這是我唯一的選擇嗎?

DECLARE @NewT2Key INT 
DECLARE @OldT2Key INT 
DECLARE @T2Value VARCHAR(50) 
DECLARE @T2KeyNewOld TABLE (OldT2Key INT, NewT2Key INT) 

DECLARE @NewGroupID INT 
DECLARE @OldGroupID INT 

SET @NewGroupID = 3 
SET @OldGroupID = 1 

-- 
-- STEP 1: CLONE THE TABLE2 DATA AND KEEP MAPPING OF OLD-to-NEW IDs 
-- 
DECLARE curT2Keys 
CURSOR FAST_FORWARD LOCAL FOR 
    SELECT t2.ID, 
     t2.T2Value 
    FROM dbo.Table2 t2 
     JOIN dbo.Table1 t1 
     ON t2.ID = t1.T2ID 
    WHERE t1.GroupID = @OldGroupID 
    ORDER BY t1.ID 

OPEN curT2Keys 
FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @NewT2Key = (SELECT MAX(ID)+1 FROM dbo.Table2) 

    INSERT INTO dbo.Table2(ID, T2Value) 
    VALUES(@NewT2Key, @T2Value) 

    INSERT INTO @T2KeyNewOld(OldT2Key, NewT2Key) 
    VALUES(@OldT2Key, @NewT2Key) 

    FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value 
END 
CLOSE curT2Keys 
DEALLOCATE curT2Keys 

-- 
-- STEP 2: CLONE THE TABLE1 DATA AND UPDATE IDs WITH NEW MAPPING 
-- 

     INSERT INTO dbo.Table1([ID], [T1Value], [T2ID], [GroupID]) 
     (SELECT 
      (SELECT MAX(ID) FROM dbo.Table1) + ROW_NUMBER() OVER (ORDER BY GroupID), 
      t1.[T1Value], 
      t2.[NewT2Key], 
      @NewGroupID 
     FROM dbo.Table1 t1 
      JOIN @T2KeyNewOld t2 
      ON t1.T2ID = t2.OldT2Key 
     WHERE t1.GroupID = @OldGroupID 
    ) 
+0

我剛剛測試了上面的代碼,它似乎適用於我。我總是覺得當我選擇在我的TSQL中使用WHILE循環時,我像一個程序員而不是像DBA一樣思考。我至少能夠在STEP 2中執行表連接。我只是希望我知道如何爲我的映射創建一個臨時表而無需使用光標。 – AmoebaMan17 2010-05-19 20:37:15