Доступ к предкам в иерархическом запросе Oracle (CONNECT BY PRIOR) - PullRequest
1 голос
/ 21 мая 2019

В настоящее время я работаю над составлением ведомости материалов для нескольких проектов и столкнулся с проблемой.

У меня есть исходная таблица со следующими столбцами:

  • Часть
  • Компонент
  • кол-во

Естественно, есть и другие столбцы, но ради простоты ...

Компонент, конечно, также может быть сборкой.

Следующий запрос даст мой иерархический вид детали и ее подкомпонентов

SELECT
    Part,
    Component,
    qty

FROM
    sourceTable

CONNECT BY
    PRIOR Component = Part

START WITH
    Part = '<Part number here>'

Хотя есть одна оговорка. Исходная таблица также содержит элементы, которые не потребляются (альтернативные элементы и т. Д.), В этом случае для столбца qty задано значение 0

.

Однако все последующие части не установлены на 0.

Я могу обойти это на подструктуре, получив доступ к элементу PRIOR qty таким образом.

SELECT
    Part,
    Component,
    qty,
    PRIOR qty * qty AS QTY_PER_MAIN_ASSEMBLY

FROM
    sourceTable

CONNECT BY
    PRIOR Component = Part

START WITH
    Part = '<Part number here>'

Как бы я поступил об этом на подсборке или на более низких уровнях в иерархии?

Мне бы хотелось узнать, как получить доступ к n-уровню PRIOR qty в этом случае

--------------------------- РЕДАКТИРОВАТЬ ------------------- --------

Разобрался с помощью какого-то поиска в Google

Используя SYS_CONNECT_BY_PATH в столбце qty, я смог построить строку, содержащую иерархию qty

После этого мне пришлось построить функцию, которая берет эту строку и разбивает ее на отдельные значения, и умножает их

CREATE OR REPLACE FUNCTION eval (expr_in IN VARCHAR2)
  RETURN NUMBER
  AUTHID CURRENT_USER
  DETERMINISTIC
  RESULT_CACHE
IS
  PRAGMA UDF;
  v_res NUMBER;
BEGIN
  EXECUTE IMMEDIATE 'SELECT ' || expr_in || ' FROM DUAL' INTO v_res;
  RETURN v_res;
END eval;

Используя вышеуказанную функцию, мне просто нужно было вставить это в мой запрос select

EVAL(SUBSTR( SYS_CONNECT_BY_PATH( TO_CHAR(qty), '*' ) , 2)) AS QTY_PER_MAIN_ASSEMBLY

1 Ответ

1 голос
/ 21 мая 2019

Вы нашли решение, но есть альтернатива, без функции, рекурсивный запрос:

with t(part, component, qty, qty_per_main_assembly) as (
    select part, component, qty, qty 
      from sourcetable 
      where part = '<Part number here>'
    union all
    select s.part, s.component, s.qty, t.qty_per_main_assembly * s.qty
      from t join sourcetable s on t.component = s.part)
select * from t

Пример dbfiddle

...