问题描述
我的表很大,有很多列,为简单起见,我只选取了相关的列。
有组件和模块。组件可以用作最终产品,但可以内置在另一个组件=模块化中。模数也一样。一个模块可以作为最终产品,也可以内置在另一个组件中。
在实际表中只有数字,但是为了更好地理解,我使用了组件关系 因此,例如componentA + componentB = modulAB,但是componentA也可以用作最终项目。 因此,在表格中有2列用于标识组件是否正在用作工厂中的最终物料 assembly_id-表示该项目是模数,因此必须具有某些组件(子代) in_assembly_id-表示该项目将内置在另一个项目/模块中
如上所述,在这两个列都为-1的情况下,它可以是最终的,但同时可以在另一个item(modul)中构建该项目,因此在我的示例中还有一行in_assembly_id -1的行。 componentA
对于已经用某些组件进行了模块化并且可以作为最终项目的项目,也可以将其内置在in_assembly_id列中指示的另一个项目(模块化)中。
我的目标是找到特定项目的模块化项目,无论该项目是否也可以作为最终产品
我可以使用join,但只能找到一个上级。
select distinct c.item,c.in_assembly_id,modul,modul_id from items c,lateral (select a.item modul,a.assembly_id modul_id from items a where a.assembly_id=c.in_assembly_id)
where c.item = 'componentA' and c.in_assembly_id <> -1;
ITEM IN_ASSEMBLY_ID MODUL MODUL_ID
componentA 100 modulAC 100
componentA 50 modulAB 50
所以要查看整个结构,因为modulAC是内置在modulACDE中的,因此需要分层查询才能看到这样的输出 1。
ITEM IN_ASSEMBLY_ID assembly_id type/level
componentA -1 50 comp
modulAB 50 -1 modul
componentA -1 100 comp
modulAC 100 -1 modul
modulAC 100 500 modul
modulACDE 500 -1 modul
最高模数
ITEM IN_ASSEMBLY_ID assembly_id type/level
componentA -1 50 comp
modulAB 50 -1 modul
componentA -1 100 comp
modulACDE 500 -1 modul
我从connect by子句开始,但是它对我不起作用,我不知道为什么得到modulDE
select distinct * from items
connect by nocycle in_assembly_id = prior assembly_id
start with item = 'componentA' and in_assembly_id <> '-1';
这是我的数据
create table items (
item_id number,item varchar2(12),assembly_id number,in_assembly_id number
);
insert into items values ( 1,'componentA',-1,-1 );
insert into items values ( 2,50 );
insert into items values ( 3,'componentB',50 );
insert into items values ( 4,'modulAB',50,-1 );
insert into items values ( 5,100 );
insert into items values ( 6,'componentC',100);
insert into items values ( 7,'modulAC',100,-1 );
insert into items values ( 7,500 );
insert into items values ( 8,'componentD',200 );
insert into items values ( 9,'componentE',200 );
insert into items values ( 10,'modulDE',200,500 );
insert into items values ( 11,'modulACDE',500,-1 );
insert into items values ( 12,'componentF',-1 );
insert into items values ( 13,'componentG',-1 );
解决方法
我的目标是为特定的商品找到
modul
的商品,这与该商品也可以作为最终商品无关紧要
这将获得modul
的所有componentA
:
SELECT CONNECT_BY_ROOT( item_id ) AS root_item_id,CONNECT_BY_ROOT( item ) AS root_item,item_id,item,assembly_id,SYS_CONNECT_BY_PATH( item_id,',' ) AS path_item_id,SYS_CONNECT_BY_PATH( item,' ) AS path_item
FROM items
WHERE assembly_id <> -1
START WITH
item = 'componentA'
AND ( assembly_id,in_assembly_id ) NOT IN ((-1,-1))
CONNECT BY NOCYCLE
PRIOR in_assembly_id = assembly_id
ORDER SIBLINGS BY item,item_id;
哪个输出:
ROOT_ITEM_ID | ROOT_ITEM | ITEM_ID | ITEM | ASSEMBLY_ID | PATH_ITEM_ID | PATH_ITEM -----------: | :--------- | ------: | :-------- | ----------: | :----------- | :------------------------------------- 2 | componentA | 4 | modulAB | 50 |,2,4 |,componentA,modulAB 2 | componentA | 7 | modulAC | 100 |,4,5,7 |,modulAB,modulAC 2 | componentA | 7 | modulAC | 100 |,6,componentC,modulAC 2 | componentA | 10 | modulDE | 200 |,8,10 |,componentD,modulDE 2 | componentA | 10 | modulDE | 200 |,9,componentE,modulDE 5 | componentA | 7 | modulAC | 100 |,7 |,modulAC 5 | componentA | 10 | modulDE | 200 |,7,modulAC,modulDE 5 | componentA | 10 | modulDE | 200 |,modulAC 5 | componentA | 11 | modulACDE | 500 |,11 |,modulACDE
db 提琴here
更新
SELECT CONNECT_BY_ROOT( item_id ) AS root_item_id,' ) AS path_item
FROM items
WHERE assembly_id > -1
START WITH
item = 'componentA'
AND ( assembly_id,-1))
CONNECT BY NOCYCLE
PRIOR in_assembly_id = assembly_id
AND assembly_id > -1
ORDER SIBLINGS BY item,item_id;
输出:
ROOT_ITEM_ID | ROOT_ITEM | ITEM_ID | ITEM | ASSEMBLY_ID | PATH_ITEM_ID | PATH_ITEM -----------: | :--------- | ------: | :-------- | ----------: | :----------- | :---------------------------- 2 | componentA | 4 | modulAB | 50 |,modulAB 5 | componentA | 7 | modulAC | 100 |,modulAC 5 | componentA | 7 | modulAC | 100 |,modulAC 5 | componentA | 11 | modulACDE | 500 |,modulACDE
db 提琴here