在Oracle 10g上需要Oracle查询BOM IMPLOSION或BOM“WHERE-USED”

时间:2011-10-31 16:28:19

标签: oracle oracle10g

使用Oracle DB 10g。

我的任务是编写BOM IMPLOSION的Oracle查询,通常称为BOM“WHERE-USED”。基本上,给定一个项目或部分,我需要提供包含该项目或部分的父项列表(如果有的话)。

我最近使用以下SQL编写了BOM EXPLOSION,该SQL利用START WITH和CONNECT BY语法从父项向下创建层次结构。我在http://www.confluentminds.com/Trainings/SCM/Topic1.1_Ch1_Part5.html

找到了BOM EXPLOSION查询的灵感

当前BOM爆炸代码:

/* BOM EXPLOSION */
select distinct
       level,
       sys_connect_by_path(msib.segment1, ' / ') as "PATH",
       msib2.segment1 as "CHILD ITEM AT LEVEL/PATH"
       /*bic.component_item_id,*/
       /*msib.inventory_item_id,*/
       /*msib2.inventory_item_id*/
from   bom.bom_components_b bic,
       bom.bom_structures_b bom,
       inv.mtl_system_items_b msib,
       inv.mtl_system_items_b msib2
where  1=1
       and bic.bill_sequence_id = bom.bill_sequence_id
       and bic.disable_date is null
       and bom.assembly_item_id = msib.inventory_item_id
       and bom.organization_id = msib.organization_id
       and bic.component_item_id = msib2.inventory_item_id
       and bom.organization_id = msib2.organization_id
       and bom.organization_id = #### /* organization id here */
       and bic.effectivity_date < sysdate
       and bom.alternate_bom_designator is null
start with msib.segment1 = '$$$$$$$$$$' /* top parent item here */
connect by nocycle prior bic.component_item_id = msib.inventory_item_id
order by level

现在,我需要从任何子项目开始,并列出包含该子项目的所有父项目。

我搜索过“oracle bom implosion”和“oracle bom where used”,但对我来说没有什么是显而易见的。 BOM IMPLOSION似乎远没有BOM爆炸那么简单。

非常感谢任何帮助或建议。

Clint Van Zee

编辑02-NOV-2011:

是的,我想遍历BOM层次结构并列出在账单中使用指定组件的那些项目或组件。

根据你的回答,我调查了“连接”关系和“开始时”。我想我有办法做到这一点。我可能在不知情的情况下接近答案。

克雷格,这是你的模型,加上修改来证明这一点。我还修改了“connect by”和“start with”。它{should!}从子组件开始,然后“向上”列出那些“使用”指定的起始组件的模型或组件。为此,我还删除了“优先”关键字。

with data
as
(
    select 'topmodel1' id, 'component1' child_id from dual union all
    select 'topmodel1' id, 'component3' child_id from dual union all
    select 'component2' id, 'component5' child_id from dual union all
    select 'component3' id, 'component4' child_id from dual union all
    select 'component4' id, 'component5' child_id from dual union all
    select 'component5' id, null child_id from dual union all
    select 'topmodel2' id, 'component1' child_id from dual union all
    select 'topmodel2' id, 'component5' child_id from dual union all
    select 'component5' id, null child_id from dual

)
select distinct
       sys_connect_by_path(id, '/') path, child_id, level
from data
start with child_id = 'component5'
connect by id = child_id
order by level

这会产生以下结果:

PATH        CHILD_ID    LEVEL
----------- ----------  -----
/component2 component5  1
/component4 component5  1
/topmodel2  component5  1

查看模拟数据,组件5由“component2”,“component4”和“topmodel2”使用。所以,这种变化似乎符合我的意图。我不得不添加可怕的“不同”,因为它不止一次遍历相同的路径。

我认为这让我更接近。

以下是我的BOM EXPLOSION代码的最小变化,以反向执行此操作:

START WITH msib.segment1 = '$$$$$$$$$$' /* child item here */
CONNECT BY nocycle msib.inventory_item_id = bic.component_item_id
ORDER BY level

当我将此更改应用于我的SQL脚本并针对实际的Oracle数据进行尝试时,CBO报告说只搜索一个组件的成本已进入平流层。所以,这种方法需要调整。

1 个答案:

答案 0 :(得分:0)

我不是100%肯定你在寻找什么,但听起来你只是想爬上树而不是下来。使用分层查询仍然可以实现这一点,您只需要更改开头并按标准连接。

举一个简单的例子:

with data
as
(
    select 1 id, 2 child_id from dual union all
    select 1 id, 3 child_id from dual union all
    select 2 id, 5 child_id from dual union all
    select 3 id, 4 child_id from dual union all
    select 4 id, 5 child_id from dual union all
    select 5 id, null child_id from dual
)
select sys_connect_by_path(id, '/') path, level
from data
start with id = 1
connect by prior child_id = id;

这将为您提供从树顶开始的子路径。要将其更改为从树中的某个点开始并向上移动,您只需使用以下内容替换/ connect开头:

start with id = 4 -- or wherever in the tree you want to start and move upwards
connect by prior id = child_id;

希望这会有所帮助。如果没有,如果你能给出一个你希望输出看起来像什么的例子,那将是非常有益的。