Sql server CTE创建产品层次结构树
我有以下三个代表产品数据的表。简而言之,产品“A”和“B”是最终产品。为了找出构成产品“A”的部件,我们查看“ProductComponents”表,该表给出了ComponentListId=1 在“PartsSubcomponents”表中查询此ComponentListId会告诉我们它有两个子组件,即A11和A12 A11很小,因为它没有进一步的子组件。然而,A12存在于“ProductComponents”表中,告诉我们它是由X1和X2组成的 最终产品Sql server CTE创建产品层次结构树,sql-server,common-table-expression,recursive-cte,Sql Server,Common Table Expression,Recursive Cte,我有以下三个代表产品数据的表。简而言之,产品“A”和“B”是最终产品。为了找出构成产品“A”的部件,我们查看“ProductComponents”表,该表给出了ComponentListId=1 在“PartsSubcomponents”表中查询此ComponentListId会告诉我们它有两个子组件,即A11和A12 A11很小,因为它没有进一步的子组件。然而,A12存在于“ProductComponents”表中,告诉我们它是由X1和X2组成的 最终产品 EndProductId A B .
EndProductId
A
B
...
产品组件
ProductId ComponentListId
A 1
A12 99
...
零部件
ComponentListId SubComponentId
1 A11
1 A12
99 X1
99 X2
...
我需要使用CTE查找产品及其零件之间的层次结构。在这种情况下,结果应如下所示:
EndProductId,ProductId,ComponentListId,SubcomponentId,Level
A, A, 1, A11, L1
A, A, 1, A12, L1
A, A12, 99, X1, L2
A, A12, 99, X2, L2
下面是一个简单的递归cte,它执行您所追求的操作并生成所需的输出:
CREATE TABLE #EndProducts
(
EndProductId NVARCHAR(1)
);
INSERT INTO #EndProducts
( EndProductId )
VALUES ( 'A' ),
( 'B' );
CREATE TABLE #ProductComponents
(
ProductId NVARCHAR(3) ,
ComponentListId INT
);
INSERT INTO #ProductComponents
( ProductId, ComponentListId )
VALUES ( 'A', 1 ),
( 'A12', 99 );
CREATE TABLE #PartsSubcomponents
(
ComponentListId INT ,
SubComponentId NVARCHAR(3)
);
INSERT INTO #PartsSubcomponents
( ComponentListId, SubComponentId )
VALUES ( 1, 'A11' ),
( 1, 'A12' ),
( 99, 'X1' ),
( 99, 'X2' );
WITH cte
AS ( -- anchor member gets level 1
SELECT e.EndProductId ,
pc.ProductId ,
sc.ComponentListId ,
sc.SubComponentId ,
1 AS [Level]
FROM #EndProducts e
INNER JOIN #ProductComponents pc
ON e.EndProductId = pc.ProductId
INNER JOIN #PartsSubcomponents sc
ON pc.ComponentListId = sc.ComponentListId
UNION ALL
-- recursive member gets the additional data and increments levels
SELECT cte.EndProductId ,
cte.SubComponentId AS ProductId ,
pc.ComponentListId ,
sc.SubComponentId ,
cte.[Level] + 1 AS [Level]
FROM cte
INNER JOIN #ProductComponents pc
ON cte.SubComponentId = pc.ProductId
INNER JOIN #PartsSubcomponents sc
ON pc.ComponentListId = sc.ComponentListId
)
SELECT *
FROM cte;
DROP TABLE #EndProducts;
DROP TABLE #PartsSubcomponents;
DROP TABLE #ProductComponents;
结果:
EndProductId ProductId ComponentListId SubComponentId Level
A A 1 A11 1
A A 1 A12 1
A A12 99 X1 2
A A12 99 X2 2
我曾想过写一个控制台应用程序,但很快就变得很糟糕。我无法将CTE的互联网示例映射到我的问题,但我仍然相信这将是最好的方法。首先,谢谢。这很有魅力!第二,你能告诉我一些好的资源吗?我可以遵循这些资源,以避免将来出现新手问题?