Иерархический SQL как связанный список - PullRequest
2 голосов
/ 21 мая 2019

У меня есть набор данных, который представляет собой набор этапов процесса для создания набора продуктов. Каждый продукт имеет последовательность шагов, определенную в наборе данных, как FromStep и ToStep. Я пытаюсь использовать иерархический запрос, чтобы выполнить шаги процесса для всех продуктов, но я явно что-то упускаю, потому что это не работает. Любой совет о том, где я ошибся, будет очень важен (возможно, это даже не способ решить эту задачу). Я попытался создать минимальный пример моей проблемы ниже - мой реальный набор данных намного больше, чем этот.

Создать образец таблицы:

CREATE TABLE HIER_TEST    
(      
    PRODUCT     VARCHAR2(26 BYTE),    
    STEPNAME    VARCHAR2(26 BYTE),    
    STEPID      NUMBER(4,0),    
    FROMSTEP    NUMBER(4,0),    
    TOSTEP      NUMBER(4,0)   
) ;   

Добавить некоторые данные:

Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product1','Step1',1,1,2);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product1','Step2',2,2,3);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product1','Step3',3,3,4);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product1','Step4',4,4,5);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product1','Step5',5,5,6);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product2','Step1',1,1,2);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product2','Step2',2,2,3);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product2','Step3',3,3,4);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product2','Step4',4,4,5);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product2','Step5',5,5,6);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product5','Step1',1,1,2);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product5','Step2',2,2,3);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product5','Step3',3,3,4);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product5','Step4',4,4,5);   
Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP) values ('Product5','Step5',5,5,6);   

Я тогда пытаюсь этот запрос:

select    
    level,   
    connect_by_isleaf leafnode,   
    hier_test.*,   
    connect_by_root stepid as rootItem   
from   
    hier_test       
start with   
    stepid = 1   
connect by nocycle prior   
    tostep = fromstep   
order siblings by   
    product,   
    stepid   
;   

, который возвращает:

+-------+-------+--------------+-----------+-------+-------+-------+-------+   
| Level | LfNd  |   Product    | StepName  | StepId| FrStp | ToStp | rtItm |   
+-------+-------+--------------+-----------+-------+-------+-------+-------+   
|   1   |   0   |   Product1   |   Step1   |   1   |   1   |   2   |   1   |   
|   2   |   0   |   Product1   |   Step2   |   2   |   2   |   3   |   1   |   
|   3   |   0   |   Product1   |   Step3   |   3   |   3   |   4   |   1   |   
|   4   |   0   |   Product1   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product1   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product2   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product5   |   Step5   |   5   |   5   |   6   |   1   |   
|   4   |   0   |   Product2   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product1   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product2   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product5   |   Step5   |   5   |   5   |   6   |   1   |   
|   4   |   0   |   Product5   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product1   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product2   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product5   |   Step5   |   5   |   5   |   6   |   1   |   
|   3   |   0   |   Product2   |   Step3   |   3   |   3   |   4   |   1   |   
|   4   |   0   |   Product1   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product1   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product2   |   Step5   |   5   |   5   |   6   |   1   |   
|   5   |   1   |   Product5   |   Step5   |   5   |   5   |   6   |   1   |   

This appears to be locked in a loop forever...

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

То, что я стремился получить, было это:

+-------+-------+--------------+-----------+-------+-------+-------+-------+   
| Level | LfNd  |   Product    | StepName  | StepId| FrStp | ToStp | rtItm |   
+-------+-------+--------------+-----------+-------+-------+-------+-------+   
|   1   |   0   |   Product1   |   Step1   |   1   |   1   |   2   |   1   |   
|   2   |   0   |   Product1   |   Step2   |   2   |   2   |   3   |   1   |   
|   3   |   0   |   Product1   |   Step3   |   3   |   3   |   4   |   1   |   
|   4   |   0   |   Product1   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product1   |   Step5   |   5   |   5   |   6   |   1   |   
|   1   |   0   |   Product2   |   Step1   |   1   |   1   |   2   |   1   |   
|   2   |   0   |   Product2   |   Step2   |   2   |   2   |   3   |   1   |   
|   3   |   0   |   Product2   |   Step3   |   3   |   3   |   4   |   1   |   
|   4   |   0   |   Product2   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product2   |   Step5   |   5   |   5   |   6   |   1   |   
|   1   |   0   |   Product5   |   Step1   |   1   |   1   |   2   |   1   |   
|   2   |   0   |   Product5   |   Step2   |   2   |   2   |   3   |   1   |   
|   3   |   0   |   Product5   |   Step3   |   3   |   3   |   4   |   1   |   
|   4   |   0   |   Product5   |   Step4   |   4   |   4   |   5   |   1   |   
|   5   |   1   |   Product5   |   Step5   |   5   |   5   |   6   |   1   |   

Я уверен, что это будет очевидно, но я не нашел ничего, что действительно помогло бы мне при попытке найти решение.

Заранее спасибо.

1 Ответ

0 голосов
/ 21 мая 2019

Результаты показывают это.

CREATE TABLE HIER_TEST    
  (      
  PRODUCT     VARCHAR2(26 BYTE),    
  STEPNAME    VARCHAR2(26 BYTE),    
  STEPID      NUMBER(4,0),    
  FROMSTEP    NUMBER(4,0),    
  TOSTEP      NUMBER(4,0)   
);

Принимая меньший подмножество ваших данных, чтобы их было проще визуализировать:

Insert into HIER_TEST (PRODUCT,STEPNAME,STEPID,FROMSTEP,TOSTEP)
SELECT 'Product1','Step1',1,1,2 FROM DUAL UNION ALL   
SELECT 'Product1','Step2',2,2,3 FROM DUAL UNION ALL   
SELECT 'Product1','Step3',3,3,4 FROM DUAL UNION ALL
SELECT 'Product2','Step1',1,1,2 FROM DUAL UNION ALL   
SELECT 'Product2','Step2',2,2,3 FROM DUAL UNION ALL   
SELECT 'Product2','Step3',3,3,4 FROM DUAL UNION ALL
SELECT 'Product5','Step1',1,1,2 FROM DUAL UNION ALL   
SELECT 'Product5','Step2',2,2,3 FROM DUAL UNION ALL   
SELECT 'Product5','Step3',3,3,4 FROM DUAL;

Затем ваш запрос с добавлением SYS_CONNECT_BY_PATH( Product, ', ' ) (вам не нужно выражение NOCYCLE, поскольку в ваших данных нет циклов):

select level,   
       connect_by_isleaf leaf,
       product,
       stepname AS sname,
       stepid AS id,
       fromstep AS fs,
       tostep AS ts,
       connect_by_root stepid as rt,
       SYS_CONNECT_BY_PATH( product, ', ' ) As path
from   hier_test       
start with
       stepid = 1   
connect by
       prior tostep = fromstep   
order siblings by   
        product,   
        stepid

Дает вывод:

LEVEL | LEAF | PRODUCT  | SNAME | ID | FS | TS | RT | PATH                          
----: | ---: | :------- | :---- | -: | -: | -: | -: | :-----------------------------
    1 |    0 | Product1 | Step1 |  1 |  1 |  2 |  1 | , Product1                    
    2 |    0 | Product1 | Step2 |  2 |  2 |  3 |  1 | , Product1, Product1          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product1, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product1, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product1, Product5
    2 |    0 | Product2 | Step2 |  2 |  2 |  3 |  1 | , Product1, Product2          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product2, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product2, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product2, Product5
    2 |    0 | Product5 | Step2 |  2 |  2 |  3 |  1 | , Product1, Product5          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product5, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product5, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product5, Product5
    1 |    0 | Product2 | Step1 |  1 |  1 |  2 |  1 | , Product2                    
    2 |    0 | Product1 | Step2 |  2 |  2 |  3 |  1 | , Product2, Product1          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product1, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product1, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product1, Product5
    2 |    0 | Product2 | Step2 |  2 |  2 |  3 |  1 | , Product2, Product2          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product2, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product2, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product2, Product5
    2 |    0 | Product5 | Step2 |  2 |  2 |  3 |  1 | , Product2, Product5          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product5, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product5, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product5, Product5
    1 |    0 | Product5 | Step1 |  1 |  1 |  2 |  1 | , Product5                    
    2 |    0 | Product1 | Step2 |  2 |  2 |  3 |  1 | , Product5, Product1          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product1, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product1, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product1, Product5
    2 |    0 | Product2 | Step2 |  2 |  2 |  3 |  1 | , Product5, Product2          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product2, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product2, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product2, Product5
    2 |    0 | Product5 | Step2 |  2 |  2 |  3 |  1 | , Product5, Product5          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product5, Product1
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product5, Product2
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product5, Product5

Затем смотрите напуть, вы можете видеть, что это упорядочено родным братом на первом уровне, затем на втором уровне и затем на третьем уровне.Это потому, что вы смотрите на продукт (и т. Д.) Только на текущей глубине, и вы не видите этот порядок.

Если вы хотите ограничить его тем же продуктом, что и на предыдущем уровне, добавьте, чток предложению CONNECT BY:

select level,   
       connect_by_isleaf leaf,
       product,
       stepname AS sname,
       stepid AS id,
       fromstep AS fs,
       tostep AS ts,
       connect_by_root stepid as rt,
       SYS_CONNECT_BY_PATH( product, ', ' ) As path
from   hier_test       
start with
       stepid = 1   
connect by
       prior tostep  = fromstep
and    prior product = product
order siblings by   
        product,   
        stepid

Какие выходы:

LEVEL | LEAF | PRODUCT  | SNAME | ID | FS | TS | RT | PATH                          
----: | ---: | :------- | :---- | -: | -: | -: | -: | :-----------------------------
    1 |    0 | Product1 | Step1 |  1 |  1 |  2 |  1 | , Product1                    
    2 |    0 | Product1 | Step2 |  2 |  2 |  3 |  1 | , Product1, Product1          
    3 |    1 | Product1 | Step3 |  3 |  3 |  4 |  1 | , Product1, Product1, Product1
    1 |    0 | Product2 | Step1 |  1 |  1 |  2 |  1 | , Product2                    
    2 |    0 | Product2 | Step2 |  2 |  2 |  3 |  1 | , Product2, Product2          
    3 |    1 | Product2 | Step3 |  3 |  3 |  4 |  1 | , Product2, Product2, Product2
    1 |    0 | Product5 | Step1 |  1 |  1 |  2 |  1 | , Product5                    
    2 |    0 | Product5 | Step2 |  2 |  2 |  3 |  1 | , Product5, Product5          
    3 |    1 | Product5 | Step3 |  3 |  3 |  4 |  1 | , Product5, Product5, Product5

db <> Fiddle здесь

...