2013-09-19 5 views
2

Я пытаюсь построить CTE или просто некоторый запрос, который берет иерархические данные из одной таблицы и вставляет его в другую таблицу, которая может иметь другой индекс. Я думал, что это будет просто, но почему-то я застрял. Я не могу заставить вывод правильно читать «RequiredID» с индексом нового посева. Btw Я работаю в SQL Server 2012.CTE для построения иерархии из исходной таблицы

Ниже я представил доказательство кода концепции, чтобы продемонстрировать, что я собираюсь сделать. Фактический SQL является более сложным, но это иллюстрирует точку.

Это то, что я получил до сих пор:

DECLARE @Table TABLE (ID INT, Code NVARCHAR(50), RequiredID INT); 

INSERT INTO @Table (ID, Code, RequiredID) VALUES 
    (1, 'Physics', NULL), 
    (2, 'Advanced Physics', 1), 
    (3, 'Nuke', 2), 
    (4, 'Health', NULL);  

DECLARE @DefaultSeed TABLE (ID INT, Code NVARCHAR(50), RequiredID INT); 

WITH hierarchy 
AS (
    --anchor 
    SELECT t.ID , t.Code , t.RequiredID 
    FROM @Table AS t 
    WHERE t.RequiredID IS NULL 

    UNION ALL 

    --recursive 
    SELECT t.ID 
      , t.Code 
      , h.ID   
    FROM hierarchy AS h 
     JOIN @Table AS t 
      ON t.RequiredID = h.ID 
    ) 

INSERT INTO @DefaultSeed (ID, Code, RequiredID) 
SELECT ID 
     , Code 
     , RequiredID 
FROM hierarchy 
OPTION (MAXRECURSION 10) 


DECLARE @NewSeed TABLE (ID INT IDENTITY(10, 1), Code NVARCHAR(50), RequiredID INT) 

--this is where I get stuck - I can't get the requiredID to read like below 
INSERT INTO @NewSeed (Code, RequiredID) 
SELECT Code, RequiredID 
FROM @DefaultSeed 

--I'm trying to get @NewSeed should read like the following... 
[ID] [Code]   [RequiredID] 
10....Physics..........NULL 
11....Health...........NULL 
12....AdvancedPhysics..10 
13....Nuke.............12 


SELECT * 
FROM @NewSeed 

Любая помощь будет принята с благодарностью!

+0

Какова ваша СУБД (Oracle, SQL Server и т.д.)? Каков ваш точный вопрос? «Я застрял *» не очень описателен. –

+0

А, хорошо, я обновил свое сообщение, чтобы сказать, что это SQL Server, который я использую сейчас – Nick

ответ

2

Вы можете использовать OUTPUT в сочетании с Merge, чтобы получить сопоставление от ID к новым идентификаторам.

Существенная часть:

--this is where you got stuck 
Declare @MapIds Table (aOldID int,aNewID int) 

;MERGE INTO @NewSeed AS TargetTable 
Using @DefaultSeed as Source on 1=0 
WHEN NOT MATCHED then 
Insert (Code,RequiredID) 
Values 
(Source.Code,Source.RequiredID) 
OUTPUT Source.ID ,inserted.ID into @MapIds; 


Update @NewSeed Set RequiredID=aNewID 
from @MapIds 
Where RequiredID=aOldID 

и весь пример:

DECLARE @Table TABLE (ID INT, Code NVARCHAR(50), RequiredID INT); 

INSERT INTO @Table (ID, Code, RequiredID) VALUES 
    (1, 'Physics', NULL), 
    (2, 'Advanced Physics', 1), 
    (3, 'Nuke', 2), 
    (4, 'Health', NULL);  

DECLARE @DefaultSeed TABLE (ID INT, Code NVARCHAR(50), RequiredID INT); 

WITH hierarchy 
AS (
    --anchor 
    SELECT t.ID , t.Code , t.RequiredID 
    FROM @Table AS t 
    WHERE t.RequiredID IS NULL 

    UNION ALL 

    --recursive 
    SELECT t.ID 
      , t.Code 
      , h.ID   
    FROM hierarchy AS h 
     JOIN @Table AS t 
      ON t.RequiredID = h.ID 
    ) 

INSERT INTO @DefaultSeed (ID, Code, RequiredID) 
SELECT ID 
     , Code 
     , RequiredID 
FROM hierarchy 
OPTION (MAXRECURSION 10) 


DECLARE @NewSeed TABLE (ID INT IDENTITY(10, 1), Code NVARCHAR(50), RequiredID INT) 

Declare @MapIds Table (aOldID int,aNewID int) 

;MERGE INTO @NewSeed AS TargetTable 
Using @DefaultSeed as Source on 1=0 
WHEN NOT MATCHED then 
Insert (Code,RequiredID) 
Values 
(Source.Code,Source.RequiredID) 
OUTPUT Source.ID ,inserted.ID into @MapIds; 


Update @NewSeed Set RequiredID=aNewID 
from @MapIds 
Where RequiredID=aOldID 


/* 
[email protected] should read like the following... 
[ID] [Code]   [RequiredID] 
10....Physics..........NULL 
11....Health...........NULL 
12....AdvancedPhysics..10 
13....Nuke.............12 
*/ 

SELECT * 
FROM @NewSeed 
+1

Если бы я мог купить только выпить! Я никогда не думал о слиянии, чтобы делать идентификационные сопоставления - я использовал его только пару раз в прошлом. – Nick

Смежные вопросы