Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Uzyskaj poziom hierarchii i wszystkie odniesienia do węzłów w Oracle

Oto rozwiązanie wykorzystujące rekurencyjne CTE. Użyłem lvl jako nagłówek kolumny od level jest słowem zastrzeżonym w Oracle. Zobaczysz również inne różnice w terminologii. Używam "rodzica" dla bezpośrednio wyższego poziomu i "przodka" dla>=0 kroków (aby dostosować się do wymagania pokazania węzła jako własnego przodka). Użyłem ORDER BY klauzula powodująca, że ​​dane wyjściowe będą pasować do twoich; możesz potrzebować zamówionych wierszy lub nie.

Twoje pytanie zachęciło mnie do ponownego, bardziej szczegółowego przeczytania o zapytaniach hierarchicznych, aby zobaczyć, czy można to zrobić z nimi zamiast z rekurencyjnymi CTE. Właściwie już wiem, że możesz, używając CONNECT_BY_PATH , ale używając substr pod tym względem samo odzyskanie najwyższego poziomu w ścieżce hierarchicznej wcale nie jest satysfakcjonujące, musi istnieć lepszy sposób. (Gdyby to był jedyny sposób na zrobienie tego z zapytaniami hierarchicznymi, zdecydowanie wybrałbym rekurencyjną ścieżkę CTE, gdyby była dostępna). Dodam tutaj hierarchiczne rozwiązanie zapytania, jeśli znajdę dobre.

with h (      node, parent ) as (
       select 1   , null  from dual union all
       select 2   , 1     from dual union all
       select 3   , 2     from dual
     ),
     r (      node  , ancestor, steps ) as (
       select node  , node    , 0    
       from   h
       union all
       select r.node, h.parent, steps + 1
       from   h join r
                on h.node = r.ancestor
     ) 
select   node, ancestor, 
         1+ (max(steps) over (partition by node)) as lvl, steps
from     r
where    ancestor is not null
order by lvl, steps desc;


      NODE   ANCESTOR        LVL      STEPS
---------- ---------- ---------- ----------
         1          1          1          0
         2          1          2          1
         2          2          2          0
         3          1          3          2
         3          2          3          1
         3          3          3          0

Dodano :Hierarchiczne rozwiązanie zapytań

OK - znalazłem to. Przetestuj oba rozwiązania, aby zobaczyć, które działa lepiej; z testów na innej konfiguracji rekurencyjne CTE było nieco szybsze niż zapytania hierarchiczne, ale może to zależeć od konkretnej sytuacji. RÓWNIEŻ:rekurencyjne CTE działa tylko w Oracle 11.2 i nowszych; rozwiązanie hierarchiczne działa ze starszymi wersjami.

Dodałem trochę więcej danych testowych, aby dopasować dane Anatolija.

with h (      node, parent ) as (
       select 1   , null  from dual union all
       select 2   , 1     from dual union all
       select 3   , 2     from dual union all
       select 4   , 2     from dual union all
       select 5   , 4     from dual
     )
select                                             node, 
           connect_by_root node                 as ancestor, 
           max(level) over (partition by node)  as lvl,
           level - 1                            as steps
from       h
connect by parent = prior node
order by   node, ancestor;



      NODE   ANCESTOR        LVL      STEPS
---------- ---------- ---------- ----------
         1          1          1          0
         2          1          2          1
         2          2          2          0
         3          1          3          2
         3          2          3          1
         3          3          3          0
         4          1          3          2
         4          2          3          1
         4          4          3          0
         5          1          4          3
         5          2          4          2
         5          4          4          1
         5          5          4          0


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Procedura składowana Oracle, zwracająca kursor ref kontra tablice asocjacyjne

  2. Oracle — ciąg kombinatoryczna permutacja

  3. Jak usunąć powtarzające się wartości kolumn z raportu?

  4. Jak napisać zapytanie, które robi coś podobnego do GROUP_CONCAT MySQL w Oracle?

  5. Jak uzyskać dwie wartości zwracane z procedury składowanej Oracle?