sql >> Databáze >  >> RDS >> Oracle

Získejte úroveň hierarchie a všechny reference uzlů na Oracle

Zde je řešení pomocí rekurzivního CTE. Použil jsem lvl jako záhlaví sloupce od level je vyhrazené slovo v Oracle. Uvidíte i další rozdíly v terminologii. Používám „rodič“ pro bezprostředně vyšší úroveň a „předek“ pro>=0 kroků (abych vyhověl vašemu požadavku na zobrazení uzlu jako jeho vlastního předka). Použil jsem ORDER BY klauzule způsobí, že výstup bude odpovídat vašemu; můžete nebo nemusíte potřebovat objednané řádky.

Vaše otázka mě podnítila, abych si znovu přečetl podrobněji o hierarchických dotazech, abych zjistil, zda to lze provést s nimi namísto rekurzivních CTE. Vlastně už vím, že můžete pomocí CONNECT_BY_PATH , ale pomocí substr na to, že jen získat nejvyšší úroveň v hierarchické cestě není vůbec uspokojivé, musí existovat lepší způsob. (Pokud by to byl jediný způsob, jak to udělat s hierarchickými dotazy, určitě bych šel rekurzivní cestou CTE, pokud by byla k dispozici). Přidám zde hierarchické řešení dotazu, pokud najdu dobré.

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

Přidáno :Hierarchické řešení dotazů

OK - našel. Vyzkoušejte prosím obě řešení, abyste zjistili, které funguje lépe; z testů na jiném nastavení byl rekurzivní CTE o něco rychlejší než hierarchický dotaz, ale to může záviset na konkrétní situaci. TAKÉ:rekurzivní CTE funguje pouze v Oracle 11.2 a vyšší; hierarchické řešení funguje se staršími verzemi.

Přidal jsem trochu více testovacích dat, aby odpovídaly Anatoliymu.

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. MySQL vyhledá a nahradí nějaký text v poli

  2. Konfigurace vysoké dostupnosti pro uzly ClusterControl pomocí CMON HA

  3. popis dotazu pomocí oracle (.Net Connector)

  4. Oracle 11G - Výkonnostní efekt indexování při vkládání