2010-05-19 49 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