Oracle найти 1-й и последний узлы в пути, CONNECT BY nocycle - PullRequest
0 голосов
/ 27 мая 2020

Я хотел бы знать, вернет ли он начало иерархии и конец иерархии для кода ниже

 WITH o AS
 (
  SELECT 'A' as obj,
         'C' as link
  FROM   dual
  UNION ALL
  SELECT 'C',
         'D'
  FROM   dual
  UNION ALL
  SELECT 'D',
         'E'
  FROM   dual
  UNION ALL
  SELECT 'X',
         'Y'
  FROM   dual),
apath AS
 (SELECT  obj,
                  link
                  , sys_connect_by_path(obj || '->' || link, ',') pth
                  , connect_by_iscycle as cy
                  , connect_by_isleaf AS lf
                  , level
  FROM   o
  CONNECT BY nocycle obj = PRIOR link)
SELECT *
FROM   apath
where lf = 1
order by pth

Я бы хотел получить результат вроде

Begin_Node, End_Node
A             E
C             E
D             E
X             Y

Текущий код возвращает

D   E   ,A->C,C->D,D->E 0   1   3
D   E   ,C->D,D->E  0   1   2
D   E   ,D->E           0   1   1
X   Y   ,X->Y           0   1   1

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

Ответы [ 2 ]

0 голосов
/ 27 мая 2020

Просто используйте CONNECT_BY_ROOT и отфильтруйте по CONNECT_BY_ISLEAF:

WITH o ( obj, link ) AS (
  SELECT 'A', 'C' FROM DUAL UNION ALL
  SELECT 'C', 'D' FROM DUAL UNION ALL
  SELECT 'D', 'E' FROM DUAL UNION ALL
  SELECT 'X', 'Y' FROM DUAL
)
SELECT CONNECT_BY_ROOT( obj ) AS begin_node,
       link AS end_node
FROM   o
WHERE  CONNECT_BY_ISLEAF = 1
CONNECT BY nocycle obj = PRIOR link;

Вывод:

BEGIN_NODE | END_NODE
:--------- | :-------
A          | E       
C          | E       
D          | E       
X          | Y       

Если вам нужны все столбцы, тогда:

WITH o ( obj, link ) AS (
  SELECT 'A', 'C' FROM DUAL UNION ALL
  SELECT 'C', 'D' FROM   dual UNION ALL
  SELECT 'D', 'E' FROM   dual UNION ALL
  SELECT 'X', 'Y' FROM   dual
)
SELECT CONNECT_BY_ROOT( obj ) AS begin_node,
       link AS end_node,
       SYS_CONNECT_BY_PATH( obj || '->' || link, ',' ) AS path,
       CONNECT_BY_ISCYCLE as iscycle,
       CONNECT_BY_ISLEAF AS isleaf,
       level
FROM   o
WHERE  CONNECT_BY_ISLEAF = 1
CONNECT BY nocycle obj = PRIOR link;

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

BEGIN_NODE | END_NODE | PATH            | ISCYCLE | ISLEAF | LEVEL
:--------- | :------- | :-------------- | ------: | -----: | ----:
A          | E        | ,A->C,C->D,D->E |       0 |      1 |     3
C          | E        | ,C->D,D->E      |       0 |      1 |     2
D          | E        | ,D->E           |       0 |      1 |     1
X          | Y        | ,X->Y           |       0 |      1 |     1

db <> fiddle здесь

0 голосов
/ 27 мая 2020

Если вас устраивает то, что представляет pth, просто извлечь из него эту информацию:

  • строка # 21: удалить начальную запятую
  • строки # 27 и # 28 возвращают начало и конец узлов

 <snip>
 18  apath AS
 19   (SELECT  obj,
 20                    link
 21                    , ltrim(sys_connect_by_path(obj || '->' || link, ','), ',') pth
 22                    , connect_by_iscycle as cy
 23                    , connect_by_isleaf AS lf
 24                    , level
 25    FROM   o
 26    CONNECT BY nocycle obj = PRIOR link)
 27  SELECT regexp_substr(pth, '^\w+') begin_node,
 28         regexp_substr(pth, '\w+$') end_node
 29  FROM   apath
 30  where lf = 1
 31  order by pth
 32  /

BEGIN_NODE END_NODE
---------- ----------
A          E
C          E
D          E
X          Y

SQL>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...