2016-11-29 3 views
0

Ich habe zwei Tabellen, die Teilenummern sowie die Hierarchie von Baugruppen nachverfolgen.SQL - Ermitteln der über- und untergeordneten Mengen auf oberster Ebene

Tabelle: Config

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

Tabelle: Unterbaugruppe

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

Ich möchte eine flache Version dieser Tabellen erstellen, die die ConfigNum (Top-Level-parent) zeigt mit allen zugehörigen Montage und Teil Nummern für jede ConfigNum in der Config-Tabelle. Die Spalte Config.AssemblyNum entspricht SubAssembly.SubAssembly.

Die Unterbaugruppe-Tabelle zeigt die Teile-zu-Kind-Beziehung zwischen Teilen. Zum Beispiel hat Versammlung 'A' eine Kinderversammlung 'AA'. Da 'AA' in der SubAssembly-Spalte existiert, ist es selbst eine Assembly und wie Sie sehen können, hat es einen Kindteil 'AAA'. 'AAA' existiert nicht in den SubAssemly-Spalten, daher ist es das letzte Kind in der Reihe.

Ich würde auch gerne eine genaue Menge Anzahl von jedem Teil basierend auf Multiplikation von Elternteil zu Kind in der Kette haben.

Zum Beispiel in der Ausgabe:

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

Beispiel Ausgabetabelle: (für Config 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 

Jeder Vorschlag, wie diese Aufgabe abzuschließen würde sehr geschätzt werden.

EDIT: Ich konnte diesen Code basierend auf den in den Antworten gemachten Vorschlägen erstellen. Ich habe immer noch Probleme, die Mengen zu multiplizieren. Ich habe den Fehler erhalten "Typen stimmen nicht überein zwischen dem Anker und dem rekursiven Teil in der Spalte" PartQty "der rekursiven Abfrage" RCTE "."

;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 

Danke,

+0

gibt es keine TEILNUM = 'A' wie in der ersten Reihe. – McNets

+0

Sie haben Recht. Ich habe die Tabelle entsprechend aktualisiert. Danke, @mcNets –

+0

gibt es irgendein Feld, das "AA" und "AAA" verbindet, außer beide haben "A"? – McNets

Antwort

0

Für dieses Problem denke ich, Sie eine rekursive Abfrage verwenden. Tatsächlich denke ich, dass die SubAssembly-Tabelle ein ProductID-Feld außer SubAssembly haben sollte, um das Hauptprodukt, das Baugruppen enthält, leicht zu identifizieren.

Sie finden ein ähnliches Beispiel in SLQ Server documentation.

Kann es hier ansehen: http://rextester.com/FQYI80157

Ändern Sie die Menge in Config-Tabelle um das Endergebnis zu ändern.

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; 

Dies ist das Ergebnis:

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

Ihre Antwort war eine große Hilfe, danke. Ich habe immer noch Probleme, die Multiplikation von Mengen zu funktionieren und bekomme einen Fehler, wenn ich versuche, in SQL Server 2014 zu laufen. Ich habe den ursprünglichen Beitrag aktualisiert, um zu zeigen, welchen Fortschritt ich gemacht habe. Jede Hilfe wird geschätzt. –

+0

SQL-Server? es ging anfangs um postgresql, oder? – McNets

+0

Ich glaube nicht. Vielleicht habe ich die Frage falsch markiert? Dies ist mein erster Beitrag, also glaube ich, dass ich nur SQl, SQL - Server markiert habe. Ihre Antwort hat immer noch sehr geholfen, da die meisten der Syntax gleich aussieht –

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] 
Verwandte Themen