BOM表中的递归SQL查询

时间:2015-11-13 15:47:48

标签: sql-server recursion recursive-query

我正在尝试从顶层开始提取项目制造中使用的所有组件,并尝试开发递归查询。经过搜索,我找不到类似的东西。 关键领域是:

  • 项目这是正在构建的项目的部分号
  • 组件这是正在使用的组件的部分号
  • 类型定义组件类型。        已购买= 0或子装配= 2

如果Component是子组件,我希望子组件组件添加到列表中(但不是子组件Part#)。如果这些组件中的任何一个本身就是一个子组件,重复等等。我有顶级列表,但无法解决如何处理递归 - 我可以找到的所有示例都有多个级别,不像我的2和循环的需要。到目前为止这是我的代码。我是SQL的相对新手。

WITH FullBom (item, comp, type) AS
(
SELECT item, comp, ref
FROM dbBOM
WHERE item = 'A Constant' AND type = 0
UNION ALL
SELECT d.item, d.comp, d.ref
FROM dbBOM d, FullBom FB
WHERE d.comp = FB.item
)
SELECT * FROM FullBom

样本数据

Item    Comp't  Type
Part1   Part2   0
Part1   Part3   0
Part1   Part4   2
Part1   Part10  2
Part1   Part11  2
Part1   …
Part4   Part5   0
Part4   Part2   0
Part4   Part6   2
Part4   Part22  2
Part4   Part23  2
Part4   …
Part6   Part7   0
Part6   Part8   0   
Part6   …

此数据的输出

Comp't  Location
Part2   Part1
Part3   Part1
Part5   Part4
Part2   Part4
Part7   Part6
Part8   Part6
...
Partxx  Part10
...
Partxx  Part11
...

我已经以准代码格式重新构建了我的查询以尝试&显示可重入结构。我希望这有助于展示我想要实现的目标。我正在尝试重新生成我们以前的数据库中的管理报告等。

Define Value as text array
Define Int as integer
Order by Item + Type ascending
                                        --Set start values
Value[1] = ‘SearchValue’
Int = 1
Find first record key ‘Value[1] + 0’
Gosub FindLoop
End

FindLoop:
While Item = Value[Int] 
    If Type = 0 then 
        Output data string
    Else Type = 2
        Int = Int + 1
        Value[Int] = Component       --Set Component as search value
        Gosub FindLoop               --Reentrant use of loop
        Int = Int – 1                --Restores previous search value
    End If
    Find Next key ‘Value + Type’
Next
Return

非常感谢您的投入。我希望我的alyout更好

由于我不知道我将在任何程序集中找到多少个子程序集,以及子程序集中有多少个子程序集,因此递归查询似乎是最好的方法。我可以使用Select,但前提是任何级别的子装配都有固定限制。由于没有限制,只要代码看到Type = 2,就需要开始挖掘直到它结束,然后循环返回等等。

1 个答案:

答案 0 :(得分:0)

你正在以与你应该做的相反的方式进行加入。

递归CTE的第一部分是锚,递归的基础,第二部分是递归。

对于锚点,因为我们没有其他字段可以理解项目是最终产品还是只有组件我们会采取一切措施,如果您是最终产品的信息过滤器。该项目的条件应该在CTE之外。

SELECT item, SubItem, [type], item AS FinalItem
FROM   dbBOM

FinalItem将始终是已完成项目的名称,并添加为在主查询中用作过滤器。

查询的递归部分将是

SELECT d.item, d.SubItem, d.[type], FB.FinalItem
FROM   FullBom FB
       Inner Join dbBOM d ON d.Item = FB.Subitem AND FB.[type] = 2

对于已存在的每一行,应该汇总([type] = 2)获取与FullBOM中的子项对应的项目,将它们添加到FullBOM并重复新项目。

FinalItem将在每个递归级别保持不变,因为我们从FullBOM读取它。

从此处获取您需要的FinalItem,只选择不需要子装配的项目([type] = 0),然后您将获得

WITH FullBom (item, SubItem, [type], FinalItem) AS
(     
  SELECT item, SubItem, [type], item AS FinalItem
  FROM   dbBOM 
  UNION ALL
  SELECT d.item, d.SubItem, d.[type], FB.FinalItem
  FROM   FullBom FB
         Inner Join dbBOM d ON d.Item = FB.Subitem AND FB.[type] = 2
)
SELECT subItem, Item
FROM   FullBom
WHERE  FinalItem= 'Part1'
  AND  [type] = 0