Следующий SQL:
WITH vehicle_build_structure (part_no, parent_part, qty_per_assembly) AS (
SELECT 'LORRY', '*', null FROM dual UNION -- if it makes things easier, you may substitute "null" for "1"
SELECT 'AXLEA', 'LORRY', 3 FROM dual UNION
SELECT 'BRAKEPAD', 'AXLEA', 2 FROM dual UNION
SELECT 'WHEEL', 'AXLEA', 4 FROM dual UNION
SELECT 'CAR', '*', null FROM dual UNION
SELECT 'AXLEB', 'CAR', 2 FROM dual UNION
SELECT 'BRAKEPAD', 'AXLEB', 2 FROM dual UNION
SELECT 'WHEEL', 'AXLEB', 2 FROM dual
), exploded_structure AS (
SELECT level lev, CONNECT_BY_ROOT s.part_no top_level_part, s.part_no, s.qty_per_assembly,
(
SELECT sum (sp.qty_per_assembly)
FROM vehicle_build_structure sp
START WITH sp.part_no = s.part_no
CONNECT BY prior sp.parent_part = sp.part_no
) sum_of_structure,
(
SELECT exp(sum(ln(sp.qty_per_assembly)))
FROM vehicle_build_structure sp
START WITH sp.part_no = s.part_no
CONNECT BY prior sp.parent_part = sp.part_no
) product_of_structure
FROM vehicle_build_structure s
START WITH s.parent_part = '*'
CONNECT BY prior s.part_no = s.parent_part
)
SELECT e.lev, e.top_level_part, e.part_no, e.qty_per_assembly,
e.sum_of_structure, e.product_of_structure
FROM exploded_structure e
Создает следующую сетку:
LEV TOP_LEVE PART_NO QTY_PER_ASSEMBLY SUM_OF_STRUCTURE PRODUCT_OF_STRUCTURE
---------- -------- -------- ---------------- ---------------- --------------------
1 CAR CAR
2 CAR AXLEB 2 2 2
3 CAR BRAKEPAD 2 9 24
3 CAR WHEEL 2 11 48
1 LORRY LORRY
2 LORRY AXLEA 3 3 3
3 LORRY BRAKEPAD 2 9 24
3 LORRY WHEEL 4 11 48
Но мне нужно, чтобы создать эту сетку:
LEV TOP_LEVE PART_NO QTY_PER_ASSEMBLY SUM_OF_STRUCTURE PRODUCT_OF_STRUCTURE
---------- -------- -------- ---------------- ---------------- --------------------
1 CAR CAR
2 CAR AXLEB 2 2 2
3 CAR BRAKEPAD 2 4 4
3 CAR WHEEL 2 4 4
1 LORRY LORRY
2 LORRY AXLEA 3 3 3
3 LORRY BRAKEPAD 2 5 6
3 LORRY WHEEL 4 7 12
Другими словами, мне нужен SQL, чтобы сказать мне, что когда я собираю автомобиль, мне нужно 4 колеса, а когда я собираю грузовик, мне нужно 12 колес.
Однако, поскольку часть WHEEL
является частью как структур CAR
, так и LORRY
, внутренний оператор connect-by-prior выполняет резервное копирование обеих ветвей и умножает количества обеих структур вместе (12 * 4 = 48). Очевидно, что когда структура становится очень сложной, это приводит к крайне неправильному ответу.
Я не могу понять, как ограничить этот внутренний оператор connect-by-before только для того, чтобы вернуться обратно в ветку от того места, куда он пришел.
Может кто-нибудь помочь?