【问题标题】:Sage Manufacturing Line 50 Bill Of Materials, SQL Recursive Two Table Tree iterationSage制造线50物料清单,SQL递归两表树迭代
【发布时间】:2014-04-10 18:39:52
【问题描述】:

我正在尝试在 MS-SQL 服务器上递归迭代 Sage 制造线 50 中的物料清单 (BOM)。

BOM 树结构包含在两个表 BOMHeader 和 BOMComponent 中。这些由 BOMHeader.ID = BOMComponent.HeaderID 链接。因此,通过链接这些并使用特定的 BomHeader.BOMReference 进行查询,我得到了 BOM 的第一层。

发生递归是因为每个 BOMComponent 本身可以是 StockCode 的程序集,如果它作为 BOMHeader.BomReference 存在,则表明它是子 BOM 并且在 BOMComponents 表中具有子组件。

我花了大约半个小时画了一张图表,但我无法发布它,因为我需要 10 个声望点

WITH BOM_CTE (HID, HRef, HDesc, SC, CDesc, CHID, CQ, SEQ)
AS
(
    SELECT H.ID as HID, H.BomReference as HRef, H.Description as HDesc, C.StockCode as SC,C.Description as CDesc,C.HeaderID as CHID,C.Quantity as CQ,1 as SEQ
    FROM [GNT\SAGEL50].[sagel50_46387].[dbo].BomHeaders H 
    JOIN [GNT\SAGEL50].[sagel50_46387].[dbo].BomComponents C
        ON H.ID = C.HeaderID
    WHERE H.BomReference like 'SA000001%'
    UNION ALL
    SELECT H.ID as HID, H.BomReference as HRef, H.Description as HDesc, C.StockCode as SC,C.Description as CDesc,C.HeaderID as CHID,C.Quantity as CQ,BC.SEQ+1
    FROM [GNT\SAGEL50].[sagel50_46387].[dbo].BomHeaders H 
    JOIN [GNT\SAGEL50].[sagel50_46387].[dbo].BomComponents C
        ON H.ID = C.HeaderID
    JOIN BOM_CTE BC
        ON HRef = BC.SC
)
Select * From BOM_CTE 

上面的代码只列出了顶层,并且不会重复,通过查看从 BOMComponents 表派生的结果股票代码是否作为 BOMReference 出现在 BOMHeader 表中(意味着它具有子组件)。

当所有 BomComponents 在 BomHeader.BomReference 中没有 StockCode 引用时,递归应该结束(意味着没有更低的级别)

我在递归SQL代码语句后,可以实现两个链接表的递归树查找。 我查看了很多 BOM 问题,但它们似乎在一张表中,而且 两个表 CTE,但我无法理解它,因为我对 SQL 相当陌生,尤其是递归。

提前感谢您的帮助

亚当

【问题讨论】:

  • 你能给我们一个更好的表结构吗?也许使用 ascii 和代码;然后查询您要做什么?现在,这读起来就像一堵文字墙,很难按照您的需要进行操作。
  • 我已经编辑过了,请您删除保留
  • 递归是否扩展了 n 级,或者树的“高”程度是否有限制? (如果限制合理,您可以对扩展进行硬编码)- PS BOM 应该意味着什么?我一直在解析“字节顺序标记”。
  • BOM 是材料清单的缩写,没有具体的深度,这取决于人们如何创建 BOM,但我怀疑,在我的情况下,深度不超过 5 或 6 级,但据我所知没有限制。
  • 这与sage无关

标签: sql-server recursion common-table-expression recursive-query


【解决方案1】:

这个线程有一个有趣的答案,并指向一个显示如何进行“硬编码”扩展的旧线程。

mysql recursive(tree) parent child category

【讨论】:

  • 感谢您的回复,但这并不是我真正想要的,而且它只有一个表,我需要两个表,我希望用 SQL Recursive CTE 来做到这一点。
【解决方案2】:
WITH BOM_CTE (HID, HRef, HDesc, SC, CDesc, CHID, CQ, SEQ)
AS
(
    --Anchor Member Definition
    SELECT H.ID as HID, H.BomReference as HRef, H.Description as HDesc, C.StockCode as SC,C.Description as CDesc,C.HeaderID as CHID,C.Quantity as CQ,1 as SEQ
    --GNT\SAGEL50.[sagel50_35648] refers to a database on a linked server on my main SQL server
    FROM [GNT\SAGEL50].[sagel50_35648].[dbo].BomHeaders H 
    JOIN [GNT\SAGEL50].[sagel50_35648].[dbo].BomComponents C
        ON H.ID = C.HeaderID
    WHERE H.BomReference like 'SA000009%'
    UNION ALL
    --Recursive Member Definition
    SELECT H.ID , H.BomReference f, H.Description , C.StockCode ,C.Description ,C.HeaderID ,C.Quantity, BC.SEQ+1
    FROM [GNT\SAGEL50].[sagel50_35648].[dbo].BomHeaders H 
    JOIN [GNT\SAGEL50].[sagel50_35648].[dbo].BomComponents C
        ON H.ID = C.HeaderID
    JOIN BOM_CTE BC
        ON H.BomReference = BC.SC
)
Select * From BOM_CTE 

现在可以使用,在我删除别名后,我现在需要做的就是传递我想要迭代的 BOMReference,而不是硬编码的 'SA000009'%

【讨论】:

    猜你喜欢
    • 2014-04-14
    • 2013-08-27
    • 2014-05-27
    • 2018-08-26
    • 2019-12-01
    • 2022-11-11
    • 2013-09-30
    • 1970-01-01
    • 2014-07-22
    相关资源
    最近更新 更多