Holen Sie sich alle Teilstrecken in einer hierarchischen Abfrage in Oracle

stimmen
0

Ich habe eine Tabelle, die eine Liste der Verkaufsabteilungen enthält wie folgt:

+-------+---------------+-----------+
|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       |
+-------+---------------+-----------+

Ich brauche eine Abfrage, die alle möglichen Teilstrecken zurückgibt. Also für die ersten drei Reihen sollte wie folgt aussehen:

5500 5510
5500 5511
5510 5511

so für jede mögliche subpath wäre es die erste und letzte Abteilung des Weges zurück. Es ist ziemlich einfach, den Weg zu erhalten, indem dies zu tun:

    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

aber wie kann ich alle möglichen Subpfade bekommen?

Veröffentlicht am 13/01/2020 um 23:56
quelle vom benutzer
In anderen Sprachen...                            


2 antworten

stimmen
0

Ich verstehe, dass Sie einen Verschluss Tabelle erstellen möchten, die alle möglichen Pfade in der Hierarchie enthält.

Hier ist eine Lösung, die eine Standard-rekursive Abfrage verwendet, das zu erreichen. Ich habe auch eine Spalte, die speichert die Tiefe der Beziehung hinzugefügt, da diese Informationen in Schließung Tabellen oft nützlich ist.

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

Diese Demo auf DB Fiddle mit Beispieldaten erzeugt 30 Zeilen, deren erste 10 sind:

VORFAHR | 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
Beantwortet am 14/01/2020 um 00:39
quelle vom benutzer

stimmen
1

Verwenden Sie CONNECT_BY_ROOTden Anfang des Weges zu finden.

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;

Abfrage :

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;

Ausgabe :

VORFAHR | DEPT_ID | PFAD                
-------: | ------: | : -------------------
    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 <> Geige hier

Beantwortet am 14/01/2020 um 00:50
quelle vom benutzer

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