Krijg alle subpaden in een hiërarchische query in Oracle

stemmen
0

Ik heb een tabel die een lijst van verkoopafdelingen bevat als volgt:

+-------+---------------+-----------+
|DEPT_ID|DEPT_NAME      |DEPT_PARENT|
+-------+---------------+-----------+
|5500   |World          |           |
|5510   |Region 1       |5500       |
|5511   |Cell 1 Region 1|5510       |
|5512   |Cell 2 Region 1|5510       |
|5513   |Cell 3 Region 1|5510       |
|5514   |Cell 4 Region 1|5510       |
|5515   |Cell 5 Region 1|5510       |
|5520   |Region 2       |5500       |
|5521   |Cell 1 Region 2|5520       |
|5522   |Cell 2 Region 2|5520       |
|5530   |Region 3       |5500       |
|5531   |Cell 1 Region 3|5530       |
|5532   |Cell 2 Region 3|5530       |
|5540   |Region 4       |5500       |
|5533   |Cell 1 Region 4|5540       |
|5534   |Cell 2 Region 4|5533       |
|5590   |Region 5       |5500       |
|5591   |Cell 1 Region 5|5590       |
+-------+---------------+-----------+

Ik heb een vraag die alle mogelijke subpaden terugkeert. Dus voor de eerste drie rijen moet het als volgt:

5500 5510
5500 5511
5510 5511

dus voor elke mogelijke subpath het zou de eerste en laatste afdeling van het pad terug te keren. Het is vrij gemakkelijk om het pad te krijgen door dit te doen:

    SELECT d.*, LTRIM (SYS_CONNECT_BY_PATH (dept_id, '-'), '-') AS PATH
      FROM depts d
START WITH dept_parent IS NULL
CONNECT BY PRIOR dept_id = dept_parent

maar hoe kan ik alle mogelijke subpaden krijgen?

De vraag is gesteld op 13/01/2020 om 21:56
bron van user
In andere talen...                            


2 antwoorden

stemmen
0

Ik begrijp dat u wilt een sluiting tafel, die alle mogelijke paden in de hiërarchie bevat genereren.

Hier is een oplossing die een standaard recursieve query om dat te bereiken. Ik voegde een kolom dat slaat de diepte van de relatie, omdat deze informatie vaak nuttig bij afsluiting tabellen.

with cte(node_id, dept_id, dept_parent, lvl) as (
    select dept_id node_id, dept_id, dept_parent, 0 lvl from dept
    union all 
    select c.node_id, d.dept_id, d.dept_parent, c.lvl + 1
    from cte c
    inner join dept d on d.dept_id = c.dept_parent
)
select dept_id ancestor, node_id node, lvl 
from cte 
where lvl > 0
order by node, ancestor

Deze demo op DB Fiddle met uw voorbeeld data produceert 30 rijen, waarvan de eerste 10 zijn:

VOORVADER | NODE | LVL
-------: | ---: | -:
    5500 | 5510 | 1
    5500 | 5511 | 2
    5510 | 5511 | 1
    5500 | 5512 | 2
    5510 | 5512 | 1
    5500 | 5513 | 2
    5510 | 5513 | 1
    5500 | 5514 | 2
    5510 | 5514 | 1
    5500 | 5515 | 2
antwoordde op 13/01/2020 om 22:39
bron van user

stemmen
1

Met CONNECT_BY_ROOThet begin van het pad te vinden.

Oracle Setup :

CREATE TABLE depts ( DEPT_ID, DEPT_NAME, DEPT_PARENT ) AS
SELECT 5500, 'World',           NULL FROM DUAL UNION ALL
SELECT 5510, 'Region 1',        5500 FROM DUAL UNION ALL
SELECT 5511, 'Cell 1 Region 1', 5510 FROM DUAL UNION ALL
SELECT 5512, 'Cell 2 Region 1', 5510 FROM DUAL UNION ALL
SELECT 5513, 'Cell 3 Region 1', 5510 FROM DUAL UNION ALL
SELECT 5514, 'Cell 4 Region 1', 5510 FROM DUAL UNION ALL
SELECT 5515, 'Cell 5 Region 1', 5510 FROM DUAL UNION ALL
SELECT 5520, 'Region 2',        5500 FROM DUAL UNION ALL
SELECT 5521, 'Cell 1 Region 2', 5520 FROM DUAL UNION ALL
SELECT 5522, 'Cell 2 Region 2', 5520 FROM DUAL UNION ALL
SELECT 5530, 'Region 3',        5500 FROM DUAL UNION ALL
SELECT 5531, 'Cell 1 Region 3', 5530 FROM DUAL UNION ALL
SELECT 5532, 'Cell 2 Region 3', 5530 FROM DUAL UNION ALL
SELECT 5540, 'Region 4',        5500 FROM DUAL UNION ALL
SELECT 5533, 'Cell 1 Region 4', 5540 FROM DUAL UNION ALL
SELECT 5534, 'Cell 2 Region 4', 5533 FROM DUAL UNION ALL
SELECT 5590, 'Region 5',        5500 FROM DUAL UNION ALL
SELECT 5591, 'Cell 1 Region 5', 5590 FROM DUAL;

Query :

SELECT CONNECT_BY_ROOT( dept_parent ) AS ancestor,
       dept_id,
       SYS_CONNECT_BY_PATH( dept_parent, '>' ) || '>' || dept_id AS path
FROM   depts
START WITH dept_parent IS NOT NULL
CONNECT BY PRIOR dept_id = dept_parent;

Output :

VOORVADER | afd-id | PAD                
-------: | ------: | : -------------------
    5500 | 5510 | > 5500> 5510          
    5500 | 5511 | > 5500> 5510> 5511     
    5500 | 5512 | > 5500> 5510> 5512     
    5500 | 5513 | > 5500> 5510> 5513     
    5500 | 5514 | > 5500> 5510> 5514     
    5500 | 5515 | > 5500> 5510> 5515     
    5500 | 5520 | > 5500> 5520          
    5500 | 5521 | > 5500> 5520> 5521     
    5500 | 5522 | > 5500> 5520> 5522     
    5500 | 5530 | > 5500> 5530          
    5500 | 5531 | > 5500> 5530> 5531     
    5500 | 5532 | > 5500> 5530> 5532     
    5500 | 5540 | > 5500> 5540          
    5500 | 5533 | > 5500> 5540> 5533     
    5500 | 5534 | > 5500> 5540> 5533> 5534
    5500 | 5590 | > 5500> 5590          
    5500 | 5591 | > 5500> 5590> 5591     
    5510 | 5511 | > 5510> 5511          
    5510 | 5512 | > 5510> 5512          
    5510 | 5513 | > 5510> 5513          
    5510 | 5514 | > 5510> 5514          
    5510 | 5515 | > 5510> 5515          
    5520 | 5521 | > 5520> 5521          
    5520 | 5522 | > 5520> 5522          
    5530 | 5531 | > 5530> 5531          
    5530 | 5532 | > 5530> 5532          
    5533 | 5534 | > 5533> 5534          
    5540 | 5533 | > 5540> 5533          
    5540 | 5534 | > 5540> 5533> 5534     
    5590 | 5591 | > 5590> 5591          

db <> fiddle hier

antwoordde op 13/01/2020 om 22:50
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more