我最近刚刚开始自学SQL,并且几乎可以从各种教程中拼凑出我需要的所有东西,但是这个让我碰到了我的脑袋。我们有一张表格,其中包含我们产品的所有物料清单信息。我只需要其中的4列 - PPN_I,CPN_I,QUANTITY_I,BOMNAME_I - 分别是项目编号,原材料编号,数量和BOMName。许多BOM都包含子装配。我需要一个列出BOM的所有组件的结果集,无论级别如何。我很确定我需要使用递归查询,但不能完全得到它,任何帮助将不胜感激。我知道还有其他几个BOM问题,但它们似乎都有不同的表格结构。所以 -
首先,我只想尝试获取一个特定项目的结果,以方便我猜测和检查工作。当我完成后,我将需要所有项目的报告,或至少一个项目列表。其中许多项目都是可配置的,并且具有多个BOM。要获得默认设置,我正在寻找空白的BOM名称。
我可以运行它并获得第一级:
select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 1 as BOMLevel
from BM010115 bm
where bm.PPN_I like '0123105-HWT' and bm.BOMNAME_I like ''
问题是一行(或多行)将具有作为子装配的cpn_i值。要查看组成子组件的内容,我需要将第一个查询的每个结果放回同一个查询中。
select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 2 as BOMLevel
from BM010115 bm
where bm.PPN_I like 'ZC-BASESUBLIM' and bm.BOMNAME_I like ''
显然,这不是最有效的方法。我尝试过,但我尝试过,但我似乎无法得到正确的结果。我已经浏览了很多不同版本的这个,这是我最近做的/最接近的。
With BMStudy as
(select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 1 as BOMLevel
from BM010115 bm
where bm.PPN_I like '0123105-HWT' and bm.BOMNAME_I like ''
UNION ALL
select bb.ppn_i, ba.cpn_i, bb.bomname_i, ba.quantity_i, 2 as BOMLevel
from BM010115 bb, BMStudy ba
where bb.BOMNAME_I like '' and ba.PPN_I = bb.CPN_I)
select * from BMStudy
这只返回第一级结果。我不相信任何BOM都超过3级,但我想有一个列来指示它的级别。有人能指出我正确的方向,或者给我一些关于我哪里出错的指示?
TL; DR - 需要查询以获取BOM中的所有组件,然后为第一个查询的所有结果提取BOM组件并将其添加到结果集。
感谢
答案 0 :(得分:4)
我认为你的逻辑基本上没问题。这有两个改进。首先,级别是递增的,因此您可以看到递归会发生什么。其次,它使用显式连接:
With BMStudy as (
select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 1 as BOMLevel
from BM010115 bm
where bm.PPN_I like '0123105-HWT' and bm.BOMNAME_I like ''
UNION ALL
select bb.ppn_i, ba.cpn_i, bb.bomname_i, ba.quantity_i, (BOMLevel + 1) as BOMLevel
from BMStudy ba join
BM010115 bb
on ba.cpn_i = bb.ppn_i
where bb.BOMNAME_I like ''
)
select * from BMStudy;
我怀疑你的问题是条件where bb.BOMNAME_I like ''
。这个值真的可能是NULL
而不是空白吗?
您还应该检查这种非递归的单级向下查询的作用:
select bb.ppn_i, ba.cpn_i, bb.bomname_i, ba.quantity_i, (BOMLevel + 1) as BOMLevel
from BM010115 ba join
BM010115 bb
on ba.cpn_i = bb.ppn_i
where bb.BOMNAME_I like '' and
(ba.PPN_I like '0123105-HWT' and ba.BOMNAME_I like '')
答案 1 :(得分:2)
With BMStudy as (
select bm.ppn_i, bm.cpn_i, bm.bomname_i, bm.QUANTITY_I, 1 as BOMLevel
from BM010115 bm
where bm.PPN_I like '0123105-HWT' and bm.BOMNAME_I like ''
UNION ALL
select ba.ppn_i, bb.cpn_i, bb.bomname_i, bb.quantity_i,
(BOMLevel + 1) as BOMLevel
from BMStudy ba join
BM010115 bb
on ba.cpn_i = bb.ppn_i
where bb.BOMNAME_I like ''
)
select top 1000 BMStudy.*, i.ITEMDESC from BMStudy, iv00101 i
where CPN_I = itemnmbr
order by BOMLEVEL, CPN_I ASC
OPTION (MAXRECURSION 0)
再次感谢!