Oracle'da hiyerarşik sorguda tüm alt yolları alın

oy
0

Ben şöyle satış bölümlerin listesini içeren bir tablo var:

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

Tüm olası alt yollar döndüren bir sorgu gerekir. aşağıdaki gibi Yani ilk üç sıra için bu olmalıdır:

5500 5510
5500 5511
5510 5511

böylece her olası alt yolun için yolun ilk ve son bölümü dönecekti. O bunu yaparak yolunu almak için oldukça kolaydır:

    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

ama nasıl tüm olası alt yollarını alabilirim?

Oluştur 13/01/2020 saat 21:56
kaynak kullanıcı
Diğer dillerde...                            


2 cevaplar

oy
0

Ben hiyerarşideki tüm olası yolları içeren bir kapatma tablo oluşturmak istiyorum anlıyoruz.

İşte bunu sağlamak için standart bir özyinelemeli sorgu kullanan bir çözümdür. Ben de bir sütun ekledi depolar ilişkinin derinliği, bu bilgiler kapatma tablolarda genellikle yararlıdır çünkü.

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

Bu DB Fiddle üzerinde demo sizin örnek verilerle kimin ilk 10 30 satır, üretir:

ANCESTOR | DÜĞÜM | 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
Cevap 13/01/2020 saat 22:39
kaynak kullanıcı

oy
1

Kullanım CONNECT_BY_ROOTyolunun başlangıcını bulmak için.

Oracle Kurulumu :

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;

Sorgu :

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;

Çıktı :

ANCESTOR | dept_id | YOL                
-------: | ------: | : -------------------
    5500 | 5510 | > 5510> 5500          
    5500 | 5511 | > 5510> 5511> 5500     
    5500 | 5512 | > 5510> 5512> 5500     
    5500 | 5513 | > 5510> 5513> 5500     
    5500 | 5514 | > 5510> 5514> 5500     
    5500 | 5515 | > 5510> 5515> 5500     
    5500 | 5520 | > 5520> 5500          
    5500 | 5521 | > 5520> 5521> 5500     
    5500 | 5522 | > 5520> 5522> 5500     
    5500 | 5530 | > 5530> 5500          
    5500 | 5531 | > 5530> 5531> 5500     
    5500 | 5532 | > 5530> 5532> 5500     
    5500 | 5540 | > 5540> 5500          
    5500 | 5533 | > 5540> 5533> 5500     
    5500 | 5534 | > 5540> 5533> 5534> 5500
    5500 | 5590 | > 5590> 5500          
    5500 | 5591 | > 5590> 5591> 5500     
    5510 | 5511 | > 5511> 5510          
    5510 | 5512 | > 5512> 5510          
    5510 | 5513 | > 5513> 5510          
    5510 | 5514 | > 5514> 5510          
    5510 | 5515 | > 5515> 5510          
    5520 | 5521 | > 5521> 5520          
    5520 | 5522 | > 5522> 5520          
    5530 | 5531 | > 5531> 5530          
    5530 | 5532 | > 5532> 5530          
    5533 | 5534 | > 5534> 5533          
    5540 | 5533 | > 5533> 5540          
    5540 | 5534 | > 5533> 5534> 5540     
    5590 | 5591 | > 5591> 5590          

db <> keman burada

Cevap 13/01/2020 saat 22:50
kaynak kullanıcı

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