2017-02-07 11 views
1

商品データを表す次の3つのテーブルがあります。簡単に説明すると、製品「A」および「B」は最終製品である。製品 "A"を作る部品を見つけるために、 "ProductComponents"テーブルを見て、ComponentListId = 1を与えます。CTE製品階層ツリーの作成

このPartsListIdに "PartsSubcomponents"テーブルを照会すると、2つのサブコンポーネントie A11およびA12。

A11はそれだけ小さく、それ以上のサブコンポーネントはありません。ただし、A12は「ProductComponents」テーブルに存在し、X1とX2で作成されていることがわかります。

最終生成物

EndProductId 
A 
B 
... 

ProductComponents

ProductId ComponentListId 
A   1 
A12  99 
... 

PartsSubcomponents

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 
+0

私はコンソールアプリケーションを作成しましたが、それはすぐに本当に汚れていました。 CTEのインターネットの例を私の問題に実際にマップすることはできませんでしたが、私はそれがそれを行う最良の方法であると考えています。 – Syed

答えて

2

は、ここでは後にしているものを行い、ご希望の出力を生成し、単純な再帰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 
+0

まずは、ありがとうございます。これは魅力のように機能します!第二に、未来の初心者の質問を避けるために私が追随できる良いリソースを教えてくれますか? – Syed