【问题标题】:CTE to build hierarchy from source tableCTE 从源表构建层次结构
【发布时间】:2013-09-19 03:03:20
【问题描述】:

我正在尝试构建一个 CTE 或只是一些查询,该查询从一个表中获取层次结构数据并将其插入可能具有不同索引的另一个表中。我认为这很简单,但由于某种原因我被卡住了。我无法使用新播种的索引在“RequiredID”上正确读取输出。顺便说一句,我正在使用 SQL Server 2012。

下面我提供了概念验证代码来展示我的目标。实际的 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

任何帮助将不胜感激!

【问题讨论】:

  • 什么是 RDBMS(Oracle、SQL Server 等)?你的确切问题是什么? “我被卡住了”的描述性不是很好。
  • 啊,好点子 - 我更新了我的帖子说这是我目前使用的 SQL Server

标签: sql sql-server sql-server-2012 common-table-expression


【解决方案1】:

您可以将OUTPUTMerge 结合使用以获取从ID 到新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


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

SELECT *
FROM @NewSeed

【讨论】:

  • 如果我只能请你喝一杯!我从没想过合并来做 ID 映射——我过去只用过几次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2013-02-21
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多