SQL 递归 CTE 'where-used' / BOM 展开第 2 部分

SQL Recursive CTE 'where-used' / BOM explosion part 2

嗨,这是从另一个post,

最初的要求已得到回答,但我意识到我现在还有另一个最终要求。我在“1”之后拥有的数据,即描述等,想要为每个级别重复,以便描述正确地标识正确的父项。我尝试在最后的 select 中再次添加列,但它只是重复了级别 1 中的项目。如何做到这一点?

* 更新 * 我真的很难让测试 data/query 看起来像我想要的那样。我想让项目通过 bomid 相互关联。输出看起来像 img.

BOM和BOMVERSION之间的关系是一个item在BOM中有多个BOMID table每个bomID在BOMVERSION中都有对应的记录,通过BOMID可以得到与BOMVERSION不同的ITEMID。该 itemID 本身可以存在于具有多个 BOMID 的 BOM table 中。我知道这很令人困惑,而且很难用测试数据来证明。这就是为什么我很乐意悬赏。

* 更新 * 根据我所学,我重做了 query/test 数据。我无法让它完全按照我的意愿行事,因此 query/data 可能需要调整或添加。我会输出我所期待的。基本上当 BOM.ItemID 通过 BOMID 链接到 BV.ItemID 时,我希望 BV.ItemID 被移动到下一个级别,然后如果 BOM.ItemID 链接到另一个 BV.ItemID 移动那个项目到下一个级别等等,以及与级别中的项目相关的所有其他信息。

IF OBJECT_ID('tempdb..#BOM') IS NOT NULL
    DROP TABLE #BOM;


CREATE TABLE #BOM
    (
      ItemID NVARCHAR(10) ,
      BOMID NVARCHAR(10) ,
      BOMQTY INT ,
      UnitID NVARCHAR(10) ,
      BOMQTYSERIE INT
    );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100001' , -- ItemID - nvarchar(10)
          N'1A' , -- BOMID - nvarchar(10)
          10 , -- BOMQTY - int
          N'g' , -- UnitID - nvarchar(10)
          5  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100001' , -- ItemID - nvarchar(10)
          N'2A' , -- BOMID - nvarchar(10)
          15 , -- BOMQTY - int
          N'kg' , -- UnitID - nvarchar(10)
          13  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100001' , -- ItemID - nvarchar(10)
          N'3A' , -- BOMID - nvarchar(10)
          16 , -- BOMQTY - int
          N'l' , -- UnitID - nvarchar(10)
          16  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100002' , -- ItemID - nvarchar(10)
          N'1A' , -- BOMID - nvarchar(10)
          18 , -- BOMQTY - int
          N'g' , -- UnitID - nvarchar(10)
          17  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100004' , -- ItemID - nvarchar(10)
          N'2A' , -- BOMID - nvarchar(10)
          20 , -- BOMQTY - int
          N'kg' , -- UnitID - nvarchar(10)
          11  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100002' , -- ItemID - nvarchar(10)
          N'2A' , -- BOMID - nvarchar(10)
          23 , -- BOMQTY - int
          N'kg' , -- UnitID - nvarchar(10)
          19  -- Bomqtyserie - int
        );

INSERT  INTO #BOM
        ( ItemID ,
          BOMID ,
          BOMQTY ,
          UnitID ,
          BOMQTYSERIE
        )
VALUES  ( N'100003' , -- ItemID - nvarchar(10)
          N'2A' , -- BOMID - nvarchar(10)
          25 , -- BOMQTY - int
          N'kg' , -- UnitID - nvarchar(10)
          21  -- Bomqtyserie - int
        );

IF OBJECT_ID('tempdb..#BOMVERSION') IS NOT NULL
    DROP TABLE #BOMVERSION;


CREATE TABLE #BOMVERSION
    (
      ItemID NVARCHAR(10) ,
      BOMID NVARCHAR(10) ,
      Name NVARCHAR(20) ,
      Active BIT
    );

INSERT  INTO #BOMVERSION
        ( ItemID ,
          BOMID ,
          Name ,
          Active
        )
VALUES  ( N'100002' , -- ItemID - nvarchar(10)
          N'1A' , -- BOMID - nvarchar(10)
          N'100002 Version' , -- Name - nvarchar(10)
          1  -- Active - bit
        );

INSERT  INTO #BOMVERSION
        ( ItemID ,
          BOMID ,
          Name ,
          Active
        )
VALUES  ( N'100002' , -- ItemID - nvarchar(10)
          N'2A' , -- BOMID - nvarchar(10)
          N'100002.1 Version' , -- Name - nvarchar(10)
          1  -- Active - bit
        );

INSERT  INTO #BOMVERSION
        ( ItemID ,
          BOMID ,
          Name ,
          Active
        )
VALUES  ( N'100003' , -- ItemID - nvarchar(10)
          N'3A' , -- BOMID - nvarchar(10)
          N'100003 Version' , -- Name - nvarchar(10)
          1  -- Active - bit
        );

INSERT  INTO #BOMVERSION
        ( ItemID ,
          BOMID ,
          Name ,
          Active
        )
VALUES  ( N'100004' , -- ItemID - nvarchar(10)
          N'4A' , -- BOMID - nvarchar(10)
          N'100004 Version' , -- Name - nvarchar(10)
          1  -- Active - bit
        );

INSERT  INTO #BOMVERSION
        ( ItemID ,
          BOMID ,
          Name ,
          Active
        )
VALUES  ( N'100005' , -- ItemID - nvarchar(10)
          N'5A' , -- BOMID - nvarchar(10)
          N'100005 Version' , -- Name - nvarchar(10)
          1  -- Active - bit
        );

IF OBJECT_ID('tempdb..#INVENTTABLE') IS NOT NULL
    DROP TABLE #INVENTTABLE;


CREATE TABLE #INVENTTABLE
    (
      ItemID NVARCHAR(10) ,
      Name NVARCHAR(20) ,
      Product INT
    );

INSERT  INTO #INVENTTABLE
        ( ItemID, Name, Product )
VALUES  ( N'100001', -- ItemID - nvarchar(10)
          N'100001 Name', -- Name - nvarchar(10)
          1  -- Product - int
          );

INSERT  INTO #INVENTTABLE
        ( ItemID, Name, Product )
VALUES  ( N'100002', -- ItemID - nvarchar(10)
          N'100002 Name', -- Name - nvarchar(10)
          2  -- Product - int
          );

INSERT  INTO #INVENTTABLE
        ( ItemID, Name, Product )
VALUES  ( N'100003', -- ItemID - nvarchar(10)
          N'100003 Name', -- Name - nvarchar(10)
          3  -- Product - int
          );

INSERT  INTO #INVENTTABLE
        ( ItemID, Name, Product )
VALUES  ( N'100004', -- ItemID - nvarchar(10)
          N'100004 Name', -- Name - nvarchar(10)
          4  -- Product - int
          );

INSERT  INTO #INVENTTABLE
        ( ItemID, Name, Product )
VALUES  ( N'100005', -- ItemID - nvarchar(10)
          N'100005 Name', -- Name - nvarchar(10)
          5  -- Product - int
          );

IF OBJECT_ID('tempdb..#ECORESPRODUCTTRANSLATION') IS NOT NULL
    DROP TABLE #ECORESPRODUCTTRANSLATION;

CREATE TABLE #ECORESPRODUCTTRANSLATION
    (
      Product INT ,
      Name NVARCHAR(20)
    );




INSERT  INTO #ECORESPRODUCTTRANSLATION
        ( Product, Name )
VALUES  ( 1, -- Product - int
          N'100001 Description'  -- Name - nvarchar(10)
          );

INSERT  INTO #ECORESPRODUCTTRANSLATION
        ( Product, Name )
VALUES  ( 2, -- Product - int
          N'100002 Description'  -- Name - nvarchar(10)
          );

INSERT  INTO #ECORESPRODUCTTRANSLATION
        ( Product, Name )
VALUES  ( 3, -- Product - int
          N'100003 Description'  -- Name - nvarchar(10)
          );

INSERT  INTO #ECORESPRODUCTTRANSLATION
        ( Product, Name )
VALUES  ( 4, -- Product - int
          N'100004 Description'  -- Name - nvarchar(10)
          );

INSERT  INTO #ECORESPRODUCTTRANSLATION
        ( Product, Name )
VALUES  ( 5, -- Product - int
          N'100005 Description'  -- Name - nvarchar(10)
          );

WITH    CTE
          AS ( SELECT   B.ItemID AS MainItem ,
                        BV.Name AS BVName ,
                        B.BOMID ,
                        BV.ItemID AS ParentItem ,
                        ECPT.Name AS ParentItemName ,
                        B.BOMQTY ,
                        B.UnitID ,
                        B.BOMQTYSERIE ,
                        1 AS [Level]
               FROM     #BOM AS B
                        JOIN #BOMVERSION AS BV ON BV.BOMID = B.BOMID
                        JOIN #INVENTTABLE AS IT ON IT.ItemID = BV.ItemID
                        JOIN #ECORESPRODUCTTRANSLATION AS ECPT ON ECPT.Product = IT.Product
               WHERE    B.ItemID = '100001'
                        AND BV.Active = 1
               UNION ALL
               SELECT   C.MainItem ,
                        C.BVName ,
                        C.BOMID ,
                        BV.ItemID ,
                        C.ParentItemName ,
                        C.BOMQTY ,
                        C.UnitID ,
                        C.BOMQTYSERIE ,
                        C.[Level] + 1
               FROM     CTE AS C
                        JOIN #BOM AS B ON C.ParentItem = B.ItemID
                        JOIN #BOMVERSION AS BV ON BV.BOMID = B.BOMID
               WHERE    C.[Level] <= 7
             )
    SELECT  MainItem ,
            [1] AS Level1 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [2] AS Level2 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [3] AS Level3 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [4] AS Level4 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [5] AS Level5 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [6] AS Level6 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE ,
            [7] AS Level7 ,
            BVName ,
            ParentItemName ,
            BOMQTY ,
            UnitID ,
            BOMQTYSERIE
    FROM    CTE PIVOT ( MAX(ParentItem) FOR [Level] IN ( [1], [2], [3], [4],
                                                         [5], [6], [7] ) ) AS pvt;

我认为你需要这种类型的转变:

select p.MainItem, p.BVName
                , left(p.[0],charindex('|',p.[0])-1) Level0_ID, REPLACE(p.[0], left(p.[0],charindex('|',p.[0])),'') Level0_Decription
                , left(p.[1],charindex('|',p.[1])-1) Level1_ID, REPLACE(p.[1], left(p.[1],charindex('|',p.[1])),'') Level1_Decription
                , left(p.[2],charindex('|',p.[2])-1) Level2_ID, REPLACE(p.[2], left(p.[2],charindex('|',p.[2])),'') Level2_Decription
                , left(p.[3],charindex('|',p.[3])-1) Level3_ID, REPLACE(p.[3], left(p.[3],charindex('|',p.[3])),'') Level3_Decription
                , left(p.[4],charindex('|',p.[4])-1) Level4_ID, REPLACE(p.[4], left(p.[4],charindex('|',p.[4])),'') Level4_Decription
                , left(p.[5],charindex('|',p.[5])-1) Level5_ID, REPLACE(p.[5], left(p.[5],charindex('|',p.[5])),'') Level5_Decription
                , left(p.[6],charindex('|',p.[6])-1) Level6_ID, REPLACE(p.[6], left(p.[6],charindex('|',p.[6])),'') Level6_Decription
                , left(p.[7],charindex('|',p.[7])-1) Level7_ID, REPLACE(p.[7], left(p.[7],charindex('|',p.[7])),'') Level7_Decription
             from (select t.MainItem, t.BVName, t.level, convert(varchar(20),t.ParentItem)+'|'+t.ParentItemName item from tree t) t
             pivot (max(item) for t.level in ([0], [1], [2], [3], [4], [5], [6], [7])) p

如果您想使用更多的列来旋转,试试这个:

select p.MainItem, p.BVName
    , p.Level0_ParentItem, p.Level0_ParentItemName
    , p.Level1_ParentItem, p.Level1_ParentItemName
    , p.Level2_ParentItem, p.Level2_ParentItemName
    , p.Level3_ParentItem, p.Level3_ParentItemName
    , p.Level4_ParentItem, p.Level4_ParentItemName
    , p.Level5_ParentItem, p.Level5_ParentItemName
    , p.Level6_ParentItem, p.Level6_ParentItemName
    , p.Level7_ParentItem, p.Level7_ParentItemName
from (
    select u.MainItem, u.BVName, 'Level'+convert(varchar(30), u.level)+'_'+u.col col, u.value
    from (select t.MainItem, t.BVName, t.level, convert(nvarchar(max),t.ParentItem) ParentItem, convert(nvarchar(max),t.ParentItemName) ParentItemName from tree t) t /*Convert all columns to the desired, but the same type*/
    unpivot (value for col in (ParentItem, ParentItemName /*and the other columns You want use*/)) u) src
pivot (max(src.value) 
    for src.col in (
        Level0_ParentItem, Level0_ParentItemName
        , Level1_ParentItem, Level1_ParentItemName
        , Level2_ParentItem, Level2_ParentItemName
        , Level3_ParentItem, Level3_ParentItemName
        , Level4_ParentItem, Level4_ParentItemName
        , Level5_ParentItem, Level5_ParentItemName
        , Level6_ParentItem, Level6_ParentItemName
        , Level7_ParentItem, Level7_ParentItemName
        )) p

在 unpivot 语句中,我为 pivot 语句创建了新列。 此解决方案的更多内容:SQL Server Pivot Table with multiple column aggregates

*** UPDATED WITH FINAL REQUIRED FORMAT ***

WITH    CTE
          AS ( SELECT   B.ITEMID AS MainItem ,
                        BV.NAME AS BVName ,
                        B.BOMID ,
                        BV.ITEMID AS ParentItem ,
                        ECPT.NAME AS ParentItemName ,
                        B.BOMQTY ,
                        B.UNITID ,
                        B.BOMQTYSERIE ,
                        1 AS [Level]
               FROM     BOM AS B
                        JOIN BOMVERSION AS BV ON BV.BOMID = B.BOMID
                        JOIN dbo.INVENTTABLE AS IT ON IT.ITEMID = BV.ITEMID
                        JOIN dbo.ECORESPRODUCTTRANSLATION AS ECPT ON ECPT.PRODUCT = IT.PRODUCT
               WHERE    B.ITEMID = '113621' /*is this really needed*/
                        AND BV.ACTIVE = 1
               UNION ALL
               SELECT   C.MainItem ,
                        C.BVName ,
                        C.BOMID ,
                        BV.ITEMID ,
                        C.ParentItemName ,
                        C.BOMQTY ,
                        C.UNITID ,
                        C.BOMQTYSERIE ,
                        C.[Level] + 1
               FROM     CTE AS C
                        JOIN BOM AS B ON C.ParentItem = B.ITEMID
                        JOIN BOMVERSION AS BV ON BV.BOMID = B.BOMID
               WHERE    C.[Level] <= 7
             ),
        TREE
          AS ( SELECT   CTE.MainItem ,
                        CTE.BVName ,
                        CTE.ParentItem ,
                        CTE.ParentItemName ,
                        CTE.BOMQTY ,
                        CTE.UNITID ,
                        CTE.BOMQTYSERIE ,
                        CTE.[Level]
               FROM     CTE
             )
    SELECT  p.MainItem ,
            p.Level1_ParentItem ,
            p.Level1_BVName ,
            p.Level1_ParentItemName ,
            p.Level1_BOMQTY ,
            p.Level1_UnitID ,
            p.Level2_ParentItem ,
            p.Level2_BVName ,
            p.Level2_ParentItemName ,
            p.Level2_BOMQTY ,
            p.Level2_UnitID ,
            p.Level3_ParentItem ,
            p.Level3_BVName ,
            p.Level3_ParentItemName ,
            p.Level3_BOMQTY ,
            p.Level3_UnitID ,
            p.Level4_ParentItem ,
            p.Level4_BVName ,
            p.Level4_ParentItemName ,
            p.Level4_BOMQTY ,
            p.Level4_UnitID ,
            p.Level5_ParentItem ,
            p.Level5_BVName ,
            p.Level5_ParentItemName ,
            p.Level5_BOMQTY ,
            p.Level5_UnitID ,
            p.Level6_ParentItem ,
            p.Level6_BVName ,
            p.Level6_ParentItemName ,
            p.Level6_BOMQTY ,
            p.Level6_UnitID ,
            p.Level7_ParentItem ,
            p.Level7_BVName ,
            p.Level7_ParentItemName ,
            p.Level7_BOMQTY ,
            p.Level7_UnitID
    FROM    ( SELECT    u.MainItem ,
                        'Level' + CAST(u.Level AS VARCHAR(20)) + '_' + u.col col ,
                        u.value
              FROM      ( SELECT    t.MainItem ,
                                    CAST(t.ParentItem AS VARCHAR(30)) AS ParentItem ,
                                    CAST(t.BVName AS VARCHAR(30)) AS BVName ,
                                    CAST(t.ParentItemName AS VARCHAR(30)) AS ParentItemName ,
                                    CAST(t.BOMQTY AS VARCHAR(30)) AS BOMQTY ,
                                    CAST(t.UNITID AS VARCHAR(30)) AS UnitID ,
                                    CAST(t.BOMQTYSERIE AS VARCHAR(30)) AS BOMQTYSERIE ,
                                    t.Level
                          FROM      TREE t
                        ) t /*Convert all columns to the desired, but the same type*/
                        UNPIVOT ( value FOR col IN ( ParentItem,
                                                     ParentItemName, BVName,
                                                     BOMQTY, UnitID,
                                                     BOMQTYSERIE                                                    
                                                      /*and the other columns You want use*/ ) ) u
            ) src PIVOT ( MAX(src.value) FOR src.col IN ( Level1_ParentItem,
                                                          Level1_BVName,
                                                          Level1_ParentItemName,
                                                          Level1_BOMQTY,
                                                          Level1_UnitID,
                                                          Level2_ParentItem,
                                                          Level2_BVName,
                                                          Level2_ParentItemName,
                                                          Level2_BOMQTY,
                                                          Level2_UnitID,
                                                          Level3_ParentItem,
                                                          Level3_BVName,
                                                          Level3_ParentItemName,
                                                          Level3_BOMQTY,
                                                          Level3_UnitID,
                                                          Level4_ParentItem,
                                                          Level4_BVName,
                                                          Level4_ParentItemName,
                                                          Level4_BOMQTY,
                                                          Level4_UnitID,
                                                          Level5_ParentItem,
                                                          Level5_BVName,
                                                          Level5_ParentItemName,
                                                          Level5_BOMQTY,
                                                          Level5_UnitID,
                                                          Level6_ParentItem,
                                                          Level6_BVName,
                                                          Level6_ParentItemName,
                                                          Level6_BOMQTY,
                                                          Level6_UnitID,
                                                          Level7_ParentItem,
                                                          Level7_BVName,
                                                          Level7_ParentItemName,
                                                          Level7_BOMQTY,
                                                          Level7_UnitID ) ) p;

这是一个易于理解和维护的版本:

    ;
WITH    CTE
          AS ( SELECT   B.RECID AS MainID ,
                        B.ITEMID AS MainItem ,
                        BV.NAME ,
                        BV.ITEMID AS ParentItem ,
                        ECPT.NAME AS ParentItemName ,
                        B.BOMQTY ,
                        B.UNITID ,
                        B.BOMQTYSERIE ,
                        0 AS [level]
               FROM     #BOM B
                        JOIN #BOMVERSION BV ON BV.BOMID = B.BOMID
                        JOIN #INVENTTABLE AS IT ON IT.ITEMID = BV.ITEMID
                        JOIN #ECORESPRODUCTTRANSLATION AS ECPT ON ECPT.PRODUCT = IT.PRODUCT
               WHERE    B.ITEMID = '113621'
                        AND BV.ACTIVE = '1'
               UNION ALL
               SELECT   C.MainID ,
                        C.MainItem ,
                        C.NAME ,
                        BV.ITEMID ,
                        C.ParentItemName ,
                        C.BOMQTY ,
                        C.UNITID ,
                        C.BOMQTYSERIE ,
                        C.[level] + 1
               FROM     CTE C
                        JOIN #BOM B ON C.ParentItem = B.ITEMID
                        JOIN #BOMVERSION BV ON BV.BOMID = B.BOMID
               WHERE    C.[level] <= 6
             )
    SELECT  B.ITEMID ,
            C1.ParentItem AS ParentItem1 ,
            C1.NAME AS BVName1 ,
            C1.ParentItemName AS ParentItemName1 ,
            C1.BOMQTY AS BomQty1 ,
            C1.UNITID AS UnitID1 ,
            C1.BOMQTYSERIE AS BomQtySerie1 ,
            C2.ParentItem AS ParentItem2 ,
            C2.NAME AS BVName2 ,
            C2.ParentItemName AS ParentItemName2 ,
            C2.BOMQTY AS BomQty2 ,
            C2.UNITID AS UnitID2 ,
            C2.BOMQTYSERIE AS BomQtySerie2 ,
            C3.ParentItem AS ParentItem3 ,
            C3.NAME AS BVName3 ,
            C3.ParentItemName AS ParentItemName3 ,
            C3.BOMQTY AS BomQty3 ,
            C3.UNITID AS UnitID3 ,
            C3.BOMQTYSERIE AS BomQtySerie3 ,
            C4.ParentItem AS ParentItem2 ,
            C4.NAME AS BVName2 ,
            C4.ParentItemName AS ParentItemName4 ,
            C4.BOMQTY AS BomQty4 ,
            C4.UNITID AS UnitID4 ,
            C4.BOMQTYSERIE AS BomQtySerie4 ,
            C5.ParentItem AS ParentItem5 ,
            C5.NAME AS BVName5 ,
            C5.ParentItemName AS ParentItemName5 ,
            C5.BOMQTY AS BomQty5 ,
            C5.UNITID AS UnitID5 ,
            C5.BOMQTYSERIE AS BomQtySerie5 ,
            C6.ParentItem AS ParentItem6 ,
            C6.NAME AS BVName6 ,
            C6.ParentItemName AS ParentItemName6 ,
            C6.BOMQTY AS BomQty6 ,
            C6.UNITID AS UnitID6 ,
            C6.BOMQTYSERIE AS BomQtySerie6 ,
            C7.ParentItem AS ParentItem7 ,
            C7.NAME AS BVName7 ,
            C7.ParentItemName AS ParentItemName7 ,
            C7.BOMQTY AS BomQty7 ,
            C7.UNITID AS UnitID7 ,
            C7.BOMQTYSERIE AS BomQtySerie7
    FROM    #BOM B
            LEFT JOIN CTE C1 ON B.RECID = C1.MainID
                                AND C1.[level] = 0
            LEFT JOIN CTE C2 ON B.RECID = C2.MainID
                                AND C2.[level] = 1
            LEFT JOIN CTE C3 ON B.RECID = C3.MainID
                                AND C3.[level] = 2
            LEFT JOIN CTE C4 ON B.RECID = C4.MainID
                                AND C4.[level] = 3
            LEFT JOIN CTE C5 ON B.RECID = C5.MainID
                                AND C5.[level] = 4
            LEFT JOIN CTE C6 ON B.RECID = C6.MainID
                                AND C6.[level] = 5
            LEFT JOIN CTE C7 ON B.RECID = C7.MainID
                                AND C7.[level] = 6
    WHERE   B.ITEMID = '113621'
            AND C1.ParentItem IS NOT NULL;

编辑:

输入:

INSERT  INTO #BOM VALUES  
( 1, N'10', N'1A' ),
( 2, N'20', N'2A' ),
( 3, N'30', N'3A' ),
( 4, N'40', N'4A' ),
( 5, N'50', N'5A' ),
( 6, N'60', N'6A' ),
( 7, N'70', N'7A' ),
( 8, N'80', N'8A' ),

( 9, N'90', N'9A' ),
( 10, N'100', N'10A' ),
( 11, N'110', N'11A' )

INSERT  INTO #BOMVERSION VALUES  
( 1, N'20', N'10 PRE', N'1A' ),
( 2, N'30', N'20 PRE', N'2A' ),
( 3, N'40', N'30 PRE', N'3A' ),
( 4, N'50', N'40 PRE', N'4A' ),
( 5, N'60', N'50 PRE', N'5A' ),
( 6, N'70', N'60 PRE', N'6A' ),
( 7, N'80', N'70 PRE', N'7A' ),

( 8, N'100', N'90 PRE', N'9A' ),
( 9, N'110', N'100 PRE', N'10A' ),
( 9, N'120', N'110 PRE', N'11A' )

INSERT  INTO #Item VALUES  
( 1, N'10', N'10 DESC' ),
( 2, N'20', N'20 DESC' ),
( 3, N'30', N'30 DESC' ),
( 4, N'40', N'40 DESC' ),
( 5, N'50', N'50 DESC' ),
( 6, N'60', N'60 DESC' ),
( 7, N'70', N'70 DESC' ),
( 8, N'80', N'80 DESC' ),

( 9, N'90', N'90 DESC' ),
( 10, N'100', N'100 DESC' ),
( 11, N'110', N'110 DESC' )

输出: