2016-11-29 44 views
0

我有兩個表跟蹤部件號以及程序集層次結構。SQL - 查找最高級別父級和副級數量

表:配置

ConfigNum AssemblyNum Qty 
    1   A  1 
    1   B  2 
    1   C  2 
    2   A  1 
    2   C  1 

表:分組件

SubAssembly PartNum Qty 
    A   AA  2 
    A   BB  4 
    A   CC  2 
    A   DD  4 
    B   EE  4 
    B   FF  8 
    AA   AAA 2 

我想與所有相關聯的組件和部件創建這些表,其示出了ConfigNum(頂級親本)的一個平面版本編號,用於配置表中的每個ConfigNum。 Config.AssemblyNum列等同於SubAssembly.SubAssembly。

部件表顯示部件之間的子部件關係。例如,大會'A'有一個小組件'AA'。由於「AA」存在於SubAssembly列中,因此它本身就是一個程序集,並且您可以看到它有一個子部分「AAA」。 'AAA'不存在於SubAssemly列中,因此它是該系列中的最後一個孩子。

我還想根據家長與孩子在連鎖店中的乘數得出每個零件的準確數量。

例如,在輸出:

(Total Qty of AAA) = (Qty A) x (Qty AA) x (Qty AAA) 
4 = 1 x 2 x 2 

示例輸出表:(對於配置1)

ConfigNum SubAssembly PartNum TotalQty 
    1   A   AA  2 
    1   A   BB  4 
    1   A   CC  2 
    1   A   DD  4 
    1   B   EE  8 
    1   B   FF  16 
    1   A   AAA  4 

,關於如何完成此任務的任何建議,將不勝感激。

編輯:我已經能夠根據在答案中提出的建議來創建此代碼。 我仍然無法獲得數量增加。 我收到了錯誤「遞歸查詢」RCTE「的列」PartQty「中的錨與遞歸部分之間的類型不匹配。」

;WITH RCTE (AssemblyNum, PartNum, PartQty, Lvl) AS 
(
    SELECT AssemblyNum, PartNum, PartQty, 1 AS Lvl 
    FROM SP_SubAssembly r1 
    WHERE EXISTS (SELECT * FROM SP_SubAssembly r2 WHERE r1.AssemblyNum = r2.PartNum) 

    UNION ALL 

    SELECT rh.AssemblyNum, rc.PartNum, (rc.PartQty * rh.PartQty), Lvl+1 AS Lvl 
    FROM dbo.SP_SubAssembly rh 
    INNER JOIN RCTE rc ON rh.PartNum = rc.AssemblyNum 
) 
SELECT CB.ID, CB.ConfigNum, CB.PartNum, CB.PartQty, r.AssemblyNum, r.PartNum, SUM(r.PartQty * COALESCE(CB.PartQty,1)) AS TotalQty 
FROM SP_ConfigBOM CB 
FULL OUTER JOIN RCTE r ON CB.PartNum = r.AssemblyNum 
WHERE CB.ConfigNum IS NOT NULL 
ORDER BY CB.ConfigNum 

感謝,

+0

沒有任何PartNum = 'A' 像你的第一行。 – McNets

+0

你是對的。我更新了表格以正確反映這一點。謝謝,@ mcNets –

+0

是否有任何鏈接「AA」和「AAA」的字段,除了都有'A'? – McNets

回答

0

對於這個問題,我認爲你必須使用一個遞歸查詢。實際上,我認爲SubAssembly表應該具有SubAssembly以外的一些ProductID字段,以便輕鬆識別包含程序集的主要產品。

您可以在SLQ Server documentation中找到類似的示例。

可以點擊此處查看:http://rextester.com/FQYI80157

變化的數量在配置表來改變最終的結果。

create temp table t1 (cfg int, part varchar(10), qty int); 
create temp table t2 (part varchar(10), sasm varchar(10), qty int); 
insert into t1 values (1,'A',2); 
insert into t2 values ('A','AA',2); 
insert into t2 values ('A','BB',4); 
insert into t2 values ('A','CC',2); 
insert into t2 values ('A','DD',4); 
insert into t2 values ('AA','AAA',2); 


WITH cte(sasm, part, qty) 
AS (
    SELECT sasm, part, qty 
    FROM #t2 WHERE part = 'A' 

    UNION ALL 

    SELECT p.sasm, p.part, p.qty * pr.qty 
    FROM cte pr, #t2 p 
    WHERE p.part = pr.sasm 
) 
SELECT #t1.cfg, cte.part, cte.sasm, SUM(cte.qty * COALESCE(#t1.qty,1)) as total_quantity 
FROM cte 
left join #t1 on cte.part = #t1.part 
GROUP BY #t1.cfg, cte.part, cte.sasm; 

這是結果:

+------+------+----------------+ 
| part | sasm | total_quantity | 
+------+------+----------------+ 
| A | AA |  4  | 
+------+------+----------------+ 
| A | DD |  8  | 
+------+------+----------------+ 
| AA | AAA |  4  | 
+------+------+----------------+ 
| A | BB |  8  | 
+------+------+----------------+ 
| A | CC |  4  | 
+------+------+----------------+ 
+0

你的回答是一個很大的幫助,謝謝。我仍然無法使數量乘法運行,並且在嘗試在SQL Server 2014中運行時收到錯誤。我更新了原始文章以顯示我已經取得的進展。任何幫助表示讚賞。 –

+0

sql服務器?它最初是關於postgresql的,是嗎? – McNets

+0

我不這麼認爲。也許我標記了錯誤的問題?這是我的第一篇文章,所以我相信我只標記它SQl,SQL - Server。你的答案仍然有很大幫助,因爲大部分語法看起來都一樣 –

0
insert into #Temp 
SELECT A.[ConfigNum] , 
      A.[AssemblyNum], 
      B.[PartNum], 
      A.[Qty], 
      A.QTY * B.Qty TotalQty 
     INTO #Temp 
     FROM [Config] A, 
      [SubAssembly] B 
     WHERE A.[AssemblyNum] = B.[SubAssembly] 

    SELECT A.[ConfigNum] , 
      A.[AssemblyNum], 
      A.[PartNum], 
      A.[Qty], 
      A.TotalQty 
    FROM #Temp A 
    union 
    SELECT A.[ConfigNum] , 
      A.[AssemblyNum], 
      B.[PartNum], 
      A.[Qty], 
      A.TotalQty * B.Qty 
    FROM #Temp A, 
    [SubAssembly] B 
    WHERE 
      A.[PartNum] = B.[SubAssembly]