我有4个表格包含我的数据:
Table COMP: definition of my component data
COMPID | NAME | DESCRIPTION
--------+-----------+------------
000123 | Comp. 1 | A44.123
000277 | Comp. 2 | A96.277
000528 | Comp. 3 | 1235287
001024 | Comp. 4 | Lollipop
004711 | Comp. 5 | Yippie
Table COMPLIST: containing the sub-components of each component
COMPID | POS | SUBCOMPID | QUANTITY
--------+------+------------ +-----------
000123 | 1 | 000277 | 3
000123 | 2 | 000528 | 1
000528 | 1 | 004711 | 1
Table COMPSUPPLIER: definition of the components suppliers
COMPID | SUPPLIER | ORDERNUMBER
--------+-----------+-------------
000123 | Supp1 | A44.123
000277 | Supp1 | A96.277
000528 | Supp2 | 1235287
001024 | Supp2 | ux12v39
004711 | Supp1 | 123456
Table ASSEMBLY: definition of my assembly
ASSYID | POS | COMPID | QUANTITY
--------+------+---------+----------
5021 | 1 | 000123 | 1
5021 | 2 | 001024 | 2
我想获得装配中使用的所有组件及其供应商和订单号(编辑:添加位置):
POS | COMPID | NAME | SUPPLIER | ORDERNUMBER | QUANTITY
-------|---------+---------+----------+-------------+----------
1 | 000123 | Comp. 1 | Supp1 | A44.123 | 1
1.1 | 000277 | Comp. 2 | Supp1 | A96.277 | 3
1.2 | 000528 | Comp. 3 | Supp2 | 1235287 | 1
1.2.1 | 004711 | Comp. 5 | Supp1 | 123456 | 1
2 | 001024 | Comp. 4 | Supp2 | ux12v39 | 2
我的想法是将SELECT与CONNECT BY结合使用,但我无法正常使用。
我目前的做法(编辑:使用GurV输入更新):
SELECT c.COMPID, c.NAME, cs.SUPPLIER, cs.ORDERNUMBER
FROM COMP c
JOIN COMPSUPPLIER cs ON c.COMPID = cs.COMPID
WHERE c.COMPID in (
SELECT COMPID
FROM ASSEMBLY
WHERE ASSYID = '5021'
UNION ALL
SELECT SUBCOMPID
FROM COMPLIST
CONNECT BY NOCYCLE PRIOR SUBCOMPID = COMPID
START WITH COMPID in (
SELECT COMPID
FROM ASSEMBLY
WHERE ASSYID = '5402')
);
有了这个,我得到了所有的子组件,但不是位置。是否有可能以某种方式得到职位栏?
答案 0 :(得分:3)
如果我遵循您的逻辑,您可以使用recursive subquery factoring而不是分层查询,这会使周期等更容易应对:
with rcte (position, compid, name, supplier, ordernumber, quantity) as (
select to_char(a.pos), a.compid, c.name, cs.supplier, cs.ordernumber, a.quantity
from assembly a
join compsupplier cs on cs.compid = a.compid
join comp c on c.compid = cs.compid
where a.assyid = 5021
union all
select rcte.position ||'.' || cl.pos, cl.subcompid, c.name,
cs.supplier, cs.ordernumber, cl.quantity
from rcte
join complist cl on cl.compid = rcte.compid
join compsupplier cs on cs.compid = cl.subcompid
join comp c on c.compid = cs.compid
)
select *
from rcte;
POSITION COMPID NAME SUPPL ORDERNU QUANTITY
---------- ------ ------- ----- ------- ----------
1 000123 Comp. 1 Supp1 A44.123 1
2 001024 Comp. 4 Supp2 ux12v39 2
1.1 000277 Comp. 2 Supp1 A96.277 3
1.2 000528 Comp. 3 Supp2 1235287 1
1.2.1 004711 Comp. 5 Supp1 123456 1
锚点成员直接从装配数据中获取前两行,包括该表中的位置 - 基本上是您的原始(前Gurv)查询,加上位置。
然后,递归成员会查看complist
每个生成的行compid
作为subcompid
存在,并将其位置附加到父级,同时获取来自其他表的其他相关数据。
如果您想在问题中显示订单时保留订单,可以在递归CTE中添加其他列,以跟踪原始位置和您当前所处的级别(可能还有其他信息可以打破关系) ,如果可能的话),并将其从最终选择列表中排除:
with rcte (position, compid, name, supplier, ordernumber, quantity,
order_by_1, order_by_2)
as (
select to_char(a.pos), a.compid, c.name, cs.supplier, cs.ordernumber, a.quantity,
a.pos, 1
from assembly a
join compsupplier cs on cs.compid = a.compid
join comp c on c.compid = cs.compid
where a.assyid = 5021
union all
select rcte.position ||'.' || cl.pos, cl.subcompid, c.name,
cs.supplier, cs.ordernumber, cl.quantity,
rcte.order_by_1, rcte.order_by_2 + 1
from rcte
join complist cl on cl.compid = rcte.compid
join compsupplier cs on cs.compid = cl.subcompid
join comp c on c.compid = cs.compid
)
select position, compid, name, supplier, ordernumber, quantity
from rcte
order by order_by_1, order_by_2;
POSITION COMPID NAME SUPPL ORDERNU QUANTITY
---------- ------ ------- ----- ------- ----------
1 000123 Comp. 1 Supp1 A44.123 1
1.1 000277 Comp. 2 Supp1 A96.277 3
1.2 000528 Comp. 3 Supp2 1235287 1
1.2.1 004711 Comp. 5 Supp1 123456 1
2 001024 Comp. 4 Supp2 ux12v39 2
答案 1 :(得分:2)
标准分层查询将适用于此问题。我在您想要的输出中看到您没有assyid
的列;如果您的企业中有多个装配,那就是一个缺陷。此外,我想在某些时候你会想要计算一个组件的子组件的总量(比如,螺钉用于组件a和组件b,两个组件都是组件1000,你需要总数螺钉数量);但是,既然你想要在适当的层次结构中展示所有东西并且#34; (如pos
列中所示),您似乎对此并不感兴趣,至少在此查询中是这样。 那个对标准的分层查询更难做,而且在递归查询中更容易做,但在这里似乎并非如此。
我们的想法是在union all
和complist
之间assembly
,添加flag
列以在分层查询的start with
子句中使用。其他一切都很标准。
with
comp ( compid, name, description ) as (
select '000123', 'Comp. 1', 'A44.123' from dual union all
select '000277', 'Comp. 2', 'A96.277' from dual union all
select '000528', 'Comp. 3', '1235287' from dual union all
select '001024', 'Comp. 4', 'Lollipop' from dual union all
select '004711', 'Comp. 5', 'Yippie' from dual
),
Complist ( compid, pos, subcompid, quantity ) as (
select '000123', 1, '000277', 3 from dual union all
select '000123', 2, '000528', 1 from dual union all
select '000528', 1, '004711', 1 from dual
),
compsupplier ( compid, supplier, ordernumber ) as (
select '000123', 'Supp1', 'A44.123' from dual union all
select '000277', 'Supp1', 'A96.277' from dual union all
select '000528', 'Supp2', '1235287' from dual union all
select '001024', 'Supp2', 'ux12v39' from dual union all
select '004711', 'Supp1', '123456' from dual
),
assembly ( assyid, pos, compid, quantity ) as (
select '5021', 1, '000123', 1 from dual union all
select '5021', 2, '001024', 2 from dual
)
select h.assyid, ltrim(h.pos, '.') as pos, h.compid,
c.name, s.supplier, s.ordernumber, h.quantity
from (
select subcompid as compid, quantity,
connect_by_root compid as assyid,
sys_connect_by_path(pos, '.') as pos
from ( select complist.*, 'f' as flag from complist
union all
select assembly.*, null as flag from assembly
)
start with flag is null
connect by compid = prior subcompid
) h
left outer join comp c on h.compid = c.compid
left outer join compsupplier s on h.compid = s.compid
;
<强>输出强>:
ASSYID POS COMPID NAME SUPPLIER ORDERNUMBER QUANTITY
------ -------- ------ ------- -------- ----------- ----------
5021 1 000123 Comp. 1 Supp1 A44.123 1
5021 1.1 000277 Comp. 2 Supp1 A96.277 3
5021 1.2 000528 Comp. 3 Supp2 1235287 1
5021 1.2.1 004711 Comp. 5 Supp1 123456 1
5021 2 001024 Comp. 4 Supp2 ux12v39 2
5 rows selected.