【问题标题】:display lowest level of componentID in recursion problem在递归问题中显示最低级别的 componentID
【发布时间】:2020-12-28 02:41:55
【问题描述】:

我正在处理制造数据,试图将组件分解为最细粒度的组件和数量。以下是一些简化的示例数据:

select *
into #assemblies
from
(
    values
    ('D', 'C', 2),
    ('C', 'B', 4),
    ('B', 'A', 3),
    ('B', 'X', 10)
) d (AssemblyID, ComponentID, Quantity);

select * from #assemblies;

这是说需要一个 D 组件 2 C 组件。
C 组件也是一个组件,必须在制作 D 之前制作。要制作 1 个 C 程序集,需要 4 个 B 程序集。
反过来 B 也是一个组件,需要 3 个 A 和 10 个 X 组件组成 1 个 B

目标是显示需要多少个AX 组件才能生成1 个D。到目前为止,这是我的尝试:

with assemblies as
(
    select Depth = 1, AssemblyID, ComponentID, NestedComponentID = ComponentID, Quantity
    from #assemblies a  --anchor member
    union all
    select Depth = a.Depth + 1, r.AssemblyID, r.ComponentID, NestedComponentID = a.ComponentID, Quantity = r.Quantity * a.Quantity
    from #assemblies r  --recursive member
    inner join assemblies a
    on r.ComponentID = a.AssemblyID
)
select * from assemblies order by AssemblyID, Depth;

虽然此查询在最深层为 AX 提供了正确的数量,但它没有显示 AX 的正确 NestedComponentID。

在红色矩形中,我希望 ComponentID 列显示 B,而 NestedComponentID 列分别显示 AX。如何修改查询以达到预期结果?

此外,此示例数据只有 3 个级别。还有其他更深的程序集,因此该解决方案也需要能够适用于更深的程序集。

【问题讨论】:

    标签: sql sql-server tsql recursion


    【解决方案1】:

    根据您的深度,Component 和 NestedComponent 之间的关系似乎非常随意。

    我的预期输出是……

    1   B   1   B    3   A   (Assembly B is made from 1 B, which is made from  3 A)
    1   B   1   B   10   X   (Assembly B is made from 1 B, which is made from 10 X)
    
    1   C   1   C    4   B   (Assembly C is made from 1 C, which is made from  4 B)
    2   C   4   B   12   A   (Assembly C is made from 4 B, which is made from 12 A)
    2   C   4   B   40   X   (Assembly C is made from 4 B, which is made from 40 X)
    
    1   D   1   D    2   C   (Assembly D is made from 1 D, which is made from  2 C)
    2   D   2   C    8   B   (Assembly D is made from 2 C, which is made from  8 B)
    3   D   8   B   24   A   (Assembly D is made from 8 B, which is made from 24 A)
    3   D   8   B   80   X   (Assembly D is made from 8 B, which is made from 80 X)
    

    那么,每一层的意思都是一致的?

    (如果您同意,我将对其进行编码。如果您不同意,请编辑您的问题以具体说明每个深度级别的每个字段的含义。)

    编辑: SQL

    WITH
      assemblyTree AS
    (
      SELECT
        0                   AS Depth,
        AssemblyID          AS AssemblyID,
        1                   AS ComponentCount,
        AssemblyID          AS ComponentID,
        Quantity            AS NestedComponentCount,
        ComponentID         AS NestedComponentID 
      FROM
        #assemblies
     
      UNION ALL
      
      SELECT
        parent.Depth + 1,
        parent.AssemblyID,
        parent.NestedComponentCount,
        parent.NestedComponentID,
        parent.NestedComponentCount * Child.Quantity,
        child.ComponentID
      FROM
        assemblyTree   AS parent
      INNER JOIN
        #assemblies    AS child
          ON parent.NestedComponentID = child.AssemblyID
    )
    SELECT
      *
    FROM
      assemblyTree
    ORDER BY
      AssemblyID,
      Depth,
      ComponentID,
      NestedComponentID
    

    https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=497a0eff8b581adbf9a0070f052b00d6

    注意:通过使顶级行与子行保持一致,一切都变得简单。

    【讨论】:

    • 是的,我同意你的预期输出。
    【解决方案2】:
    ;WITH assemblie_line
    AS (
        SELECT  AssemblyID  , 
                ComponentID ,
                Quantity
        FROM #assemblies
        WHERE AssemblyID = 'D'
    
        UNION ALL
    
        SELECT  L.AssemblyID                ,
                A.ComponentID               ,
                L.Quantity * A.Quantity
        FROM assemblie_line L
        JOIN #assemblies A ON A.AssemblyID = L.ComponentID
    )
    SELECT * 
    FROM assemblie_line X
    WHERE X.ComponentID = 'X'
    

    【讨论】:

      猜你喜欢
      • 2021-01-27
      • 2021-11-30
      • 2021-10-20
      • 1970-01-01
      • 2012-02-21
      • 2010-11-03
      • 2014-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多