Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Dapatkan level Hierarki dan semua referensi node di Oracle

Berikut adalah solusi menggunakan CTE rekursif. Saya menggunakan lvl sebagai tajuk kolom sejak level adalah kata yang dicadangkan di Oracle. Anda akan melihat perbedaan lain dalam terminologi juga. Saya menggunakan "induk" untuk level yang lebih tinggi dan "leluhur" untuk>=0 langkah (untuk mengakomodasi kebutuhan Anda untuk menunjukkan simpul sebagai leluhurnya sendiri). Saya menggunakan ORDER BY klausa untuk menyebabkan output cocok dengan milik Anda; Anda mungkin atau mungkin tidak membutuhkan baris yang dipesan.

Pertanyaan Anda mendorong saya untuk membaca lagi, secara lebih rinci, tentang kueri hierarkis, untuk melihat apakah ini dapat dilakukan dengan mereka alih-alih CTE rekursif. Sebenarnya saya sudah tahu Anda bisa, dengan menggunakan CONNECT_BY_PATH , tetapi menggunakan substr pada itu hanya untuk mengambil tingkat atas dalam jalur hierarkis tidak memuaskan sama sekali, harus ada cara yang lebih baik. (Jika itu satu-satunya cara untuk melakukannya dengan kueri hierarkis, saya pasti akan menggunakan rute CTE rekursif jika tersedia). Saya akan menambahkan solusi kueri hierarkis di sini, jika saya dapat menemukan solusi yang bagus.

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

Ditambahkan :Solusi kueri hierarki

Oke - menemukannya. Silakan uji kedua solusi untuk melihat mana yang berkinerja lebih baik; dari pengujian pada pengaturan yang berbeda, CTE rekursif sedikit lebih cepat daripada kueri hierarkis, tetapi itu mungkin tergantung pada situasi spesifik. JUGA:CTE rekursif hanya berfungsi di Oracle 11.2 dan di atasnya; solusi hierarki berfungsi dengan versi yang lebih lama.

Saya menambahkan sedikit lebih banyak data pengujian untuk mencocokkan Anatoliy.

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. Menggunakan sql/plsql, bagaimana Anda mengetahui set karakter mana yang digunakan teks?

  2. Oracle <> , !=, ^=operator

  3. Oracle dinamis DESC dan ASC diurutkan oleh

  4. ATAN2() Fungsi di Oracle

  5. Masalah NHibernate TransactionScope dengan Oracle 11g