2016-08-02 12 views
0

У меня есть таблица, но я не могу написать отношение для извлечения дерева.Как создать иерархический запрос в Oracle?

Вот пример данных:

LOT_ID | LOT_PRODUCED | ITEM_PRODUCED | ITEM_USED | LOT_USED | OPERATION | STEP 
------ | ------------ | ------------- | --------- | -------- | --------- | ---- 
1  | LOT_1  | ITEM_1  | null  | null  | P   | STEP_1 
1  | null   | null   | ITEM_1 | LOT_1 | C   | STEP_2 
5  | null   | null   | ITEM_2 | LOT_2 | C   | STEP_2 
5  | LOT_2  | ITEM_2  | null  | null  | P   | STEP_8 
5  | null   | null   | ITEM_2 | LOT_2 | C   | STEP_1 
6  | null   | null   | ITEM_2 | LOT_7 | C   | STEP_8 

Начиная с LOT_PRODUCED = LOT_1, я хотел бы иметь дерево с каждым шагом, связанным с этапом начальной партии.

Итак, в этом примере мы видим, что STEP_1 (шаг, который произвел LOT_1) потребляет LOT_2. Эта партия была произведена STEP_8. Этот шаг, в свою очередь, потребляет LOT_7. И так далее.

Я думаю, что понимаю концепцию START WITH и CONNECT BY, но я не могу решить этот случай, поскольку ссылка «прыгает» между столбцами. Определенных родительских и дочерних элементов нет.

Если это не разрешено простым запросом, я открыт для хранимой процедуры.

Edit:

Here is a drawing of the data shown above

Итак, на левом есть объяснения ссылок:

  • много потребляемых шагом
  • шаг производит много

И справа есть ссылки: номер на линии связи ectors - номер строки данных, показанных выше.

+0

Очистить как грязь.Какая строка показывает, что LOT_1 потребляет LOT_2? В вашей таблице нет строки, чтобы показать какую-либо связь между ними, либо напрямую, либо цепочкой других строк. (Если есть, объясните.) – mathguy

+0

Похоже, у вас есть три перечислимых объекта: партии, предметы и шаги. Однако я не думаю, что ясно, какова взаимосвязь между этими вещами - отредактируйте свой вопрос, чтобы указать (примерно), что это за вещи. Он выглядит как шаг _produces_ item, шаг _uses_ item и шаг _uses_ много. Вы уточните? – halfer

+0

Вы можете обнаружить, что графическое представление, встроенное в ваш вопрос, помогает проиллюстрировать проблему. – halfer

ответ

0

Я придумал запрос:

SELECT DISTINCT G.STEP, 
    LOT_USED, 
    ITEM_USED, 
    LOT_PRODUCED, 
    ITEM_PRODUCED 
FROM GENEALOGY G 
    START WITH G.STEP  = 'STEP01' 
    CONNECT BY LOTPRODUCED = PRIOR LOTUSED 
AND ITEMPRODUCED   = PRIOR ITEMUSED 
ORDER BY G.STEP 

Но это возвращает только первый уровень потреблений: от исходного шага, я получаю много потребляется, а затем для каждого из этих лотов, я получаю шаг, который его создал. Я также получаю партию, произведенную стартовым шагом, если таковой имеется.

Чтобы связать с моим, например, данные, я получаю (начиная с step_1):

STEP | LOT_USED | ITEM_USED | LOT_PRODUCED | ITEM_PRODUCED 
-------|----------|-----------|--------------|--------------- 
STEP_1 | LOT_2 | ITEM_2 |    | 
STEP_1 |   |   | LOT_1  | ITEM_1 
STEP_8 |   |   | LOT_2  | ITEM_2 

Затем я изменил запрос, чтобы включить существующую часть в качестве подзапроса:

SELECT DISTINCT H.STEP, 
    LOTUSED, 
    ITEMUSED, 
    LOTPRODUCED, 
    ITEMPRODUCED 
FROM GENEALOGY H 
    START WITH H.STEP IN 
    (SELECT DISTINCT G.STEP 
    FROM GENEALOGY G 
     START WITH G.STEP = 'STEP_1' 
     CONNECT BY LOTPRODUCED = PRIOR LOTUSED 
    AND ITEMPRODUCED   = PRIOR ITEMUSED 
    ) 
    CONNECT BY LOTPRODUCED = PRIOR LOTUSED 
AND ITEMPRODUCED   = PRIOR ITEMUSED 
ORDER BY H.STEP 

I затем получите 2 уровня потребления.

Чтобы связать с моим, например, данные, я получаю (начиная с step_1):

STEP | LOT_USED | ITEM_USED | LOT_PRODUCED | ITEM_PRODUCED 
-------|----------|-----------|--------------|--------------- 
STEP_1 | LOT_2 | ITEM_2 |    | 
STEP_1 |   |   | LOT_1  | ITEM_1 
STEP_8 |   |   | LOT_2  | ITEM_2 
STEP_8 | LOT_7 | ITEM_2 |    | 

Так что я могу получить столько уровень потреблений как CONNECT BY присутствует в запросе. Но я, конечно, хотел бы получить полное дерево. Я не знаю количества уровней заранее, и даже если бы знал, что это, например, 30, мой запрос будет «огромным» без причины.

У кого-то есть идея помочь мне построить более простой запрос для моей проблемы? Возможно, работайте с полем P (произвести) и C (потреблять) OPERATION и LOT_ID?