【问题标题】:SQL Server 2005 - CTE, retaining values and inserting in datasetsSQL Server 2005 - CTE,保留值并插入数据集中
【发布时间】:2010-01-12 01:25:55
【问题描述】:

假设您有一个这样的表(SQL SERVER 2005)

pairID childID parentID
 0       1      2
 1       2      3
 2       3      4

你有一个返回这个数据集的 CTE:

pairID childID parentID level
 0       1      2        2
 1       2      3        1
 2       3      4        0

如何保存初始子 ID 以便获得此结果集:

pairID childID parentID level
 0       1      2        2
 1       1      3        1
 2       1      4        0

所以基本上我正在做的是保留原始子 ID 并返回它而不是另一个......

这是迄今为止的 CTE 查询,效果很好:

WITH TESTER AS (SELECT a.PairID,
                a.ChildID,
                a.ParentID,
                0 AS Level
                FROM
                BusinessHierarchy AS a 
                LEFT OUTER JOIN BusinessHierarchy AS a2 
                ON a.ParentID = a2.ChildID
                WHERE (a2.PairID IS NULL)
                UNION ALL
                SELECT b.PairID, b.ChildID, b.ParentID, oh.Level + 1 AS Level
                FROM BusinessHierarchy AS b INNER JOIN
                TESTER AS oh ON b.ParentID = oh.ChildID)
SELECT PairID, ChildID, ParentID, Level
 FROM  TESTER AS x
 ORDER BY Level, ChildID, ParentID

【问题讨论】:

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


    【解决方案1】:

    你可以先得到它(进入一个变量),然后再使用这个变量。

    DECLARE @StartingId int
    
    SELECT
        @StartingId = a.PairID
    FROM BusinessHierarchy AS a 
    LEFT OUTER JOIN BusinessHierarchy AS a2 ON a.ParentID = a2.ChildID
    WHERE (a2.PairID IS NULL)
    
    
    WITH TESTER AS (SELECT a.PairID,
                a.ChildID,
                a.ParentID,
                0 AS Level
                FROM
                BusinessHierarchy AS a 
                WHERE (a.PairID = @StartingId)
                UNION ALL
                SELECT b.PairID, b.ChildID, b.ParentID, oh.Level + 1 AS Level
                FROM BusinessHierarchy AS b INNER JOIN
                TESTER AS oh ON b.ParentID = oh.ChildID)
    
    SELECT PairID, @StartingId, ParentID, Level
    FROM  TESTER AS x
    ORDER BY Level, ChildID, ParentID
    

    【讨论】:

    • 这不是只发生一次吗,@StartingID 的初始填充?每个不同的层级组会发生什么情况?
    • 它只发生一次。如果您希望它发生更多,您必须向我们提供有关您在表格中的内容以及您想用它做什么的更多信息。
    【解决方案2】:

    未经测试,但您尝试过吗?

    ;WITH My_CTE AS
    (
         SELECT
              BH1.PairID,
              BH1.ChildID AS BaseID,
              BH1.ChildID,
              BH1.ParentID,
              0 AS Level
         FROM
              BussinessHierarchy BH1
         LEFT OUTER JOIN BussinessHierarchy BH2 ON
              BH1.ParentID = BH2.ChildID
         WHERE
              BH2.PairID IS NULL
         UNION ALL
         SELECT
              BH3.PairID,
              CTE.BaseID,
              BH3.ChildID,
              BH3.ParentID,
              CTE.Level + 1 AS Level
         FROM
              My_CTE CTE
         INNER JOIN BussinessHierarchy BH3 ON
              BH3.ParentID = CTE.ChildID
         )
    SELECT
         PairID,
         BaseID,
         ParentID,
         Level
    FROM
         My_CTE
    ORDER BY
         Level,
         BaseID,
         ParentID
    

    【讨论】:

    • 我做到了,但在我调试错误之前它一直在使我的 IDE 崩溃。我会继续努力的。
    【解决方案3】:

    恐怕您写的 CTE 让我感到困惑,所以我将其重写如下,它给出了您所要求的结果。这符合您的要求吗?

    WITH List (pairID, childId, parentId, level, originalid )
    AS
    (
        -- Anchor member definition
        select pairID, childID, parentID, 0 as level, ChildID as originalid
        FROM    
        BusinessHeirarchy bh
        where bh.PairID = 0
    
    
        UNION ALL
    
        -- Recursive member definition
        select j.pairId, j.childID, j.parentID, lst.level +1 as level, lst.originalid
        from BusinessHeirarchy j inner join List lst 
        on  (lst.parentId = j.ChildID)
    
    )
    
    select * from list;
    

    您显然可以根据需要使用输出列和顺序,但该数据符合您的要求。

    使用我的 sql 时要注意的一件事是,我限制了基于零对的锚查询,因为您的示例数据没有空值。如果你需要空检查来拉出你的锚,这应该很容易改变。

    然后,我只需使用附加列 OriginalId 加入父子关系,该列包含锚查询中的第一个 childId。

    【讨论】:

    • 当我更正“层次结构”错误并运行它时,我不确定错误是什么,我的 IDE 只是崩溃了。另一个问题是它们有很多这样的关系,上面只是一个低端的例子。
    • 你的 IDE 崩溃了?!你是说管理工作室吗?提供的代码在提供的数据上运行良好。问题可能与数据有关吗?如果您从 Visual Studio 运行它,可能是它不能很好地处理达到最大递归时引发的错误。
    • 这是真的,是的,我在 Visual Studio 中运行它。上面的例子是一个小例子,我使用原始查询在我的数据集中返回了 800 行,我无法让上面的那个工作,对不起,这对我来说仍然是一个新概念。
    • 在管理工作室(Visual Studio IDE 的 SQL 服务器等价物)中运行它会发生什么?你能得到更好的错误信息吗?使用这种 SQL,我总能找到解决它的最佳方法,就是从小处着手并逐步完善。当您只运行查询的锚部分时会发生什么?如果您手动运行第二个连接(将其输入到管理工作室)呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多