SQL - 查找顶级父级和乘法数量

时间:2016-11-29 19:06:04

标签: sql sql-server

我有两个表跟踪零件编号以及装配体的层次结构。

表:配置

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

表:SubAssembly

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(顶级父级)以及Config表中每个ConfigNum的所有关联程序集和部件号。 Config.AssemblyNum列等同于SubAssembly.SubAssembly。

“子装配”表显示零件之间的子配对关系。例如,程序集“A”具有子程序集“AA”。由于SubAssembly列中存在'AA',因此它是一个自组装,你可以看到它有一个子组件'AAA'。 SubAssemly列中不存在“AAA”,因此它是该系列中的最后一个子节点。

我还希望根据父母与子女之间的乘数来确定每个部分的准确数量。

例如在输出中:

(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

谢谢,

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:0)

对于这个问题,我认为你必须使用递归查询。事实上,我认为SubAssembly表应该有一些除SubAssembly之外的ProductID字段,以便轻松识别包含程序集的主要产品。

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

可在此处查看:http://rextester.com/FQYI80157

更改Config表中的数量以更改最终结果。

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