Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Nhận cấp độ phân cấp và tất cả các tham chiếu nút trên Oracle

Đây là một giải pháp sử dụng CTE đệ quy. Tôi đã sử dụng lvl làm tiêu đề cột kể từ level là một từ dành riêng trong Oracle. Bạn cũng sẽ thấy những khác biệt khác về thuật ngữ. Tôi sử dụng "cha" cho cấp cao hơn ngay lập tức và "tổ tiên" cho> =0 bước (để đáp ứng yêu cầu của bạn về việc hiển thị một nút làm tổ tiên của nó). Tôi đã sử dụng ORDER BY mệnh đề khiến đầu ra khớp với kết quả của bạn; bạn có thể cần hoặc không cần các hàng được sắp xếp.

Câu hỏi của bạn đã kích thích tôi đọc lại, chi tiết hơn, về các truy vấn phân cấp, để xem liệu điều này có thể được thực hiện với chúng thay vì các CTE đệ quy hay không. Trên thực tế, tôi biết bạn có thể làm được, bằng cách sử dụng CONNECT_BY_PATH , nhưng sử dụng substr trên đó chỉ để truy xuất cấp cao nhất trong một đường dẫn phân cấp là không thỏa mãn chút nào, phải có một cách tốt hơn. (Nếu đó là cách duy nhất để làm điều đó với các truy vấn phân cấp, tôi chắc chắn sẽ đi theo tuyến CTE đệ quy nếu nó có sẵn). Tôi sẽ thêm giải pháp truy vấn phân cấp ở đây, nếu tôi có thể tìm thấy giải pháp tốt.

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

Đã thêm :Giải pháp truy vấn phân cấp

OK - đã tìm thấy nó. Vui lòng kiểm tra cả hai giải pháp để xem giải pháp nào hoạt động tốt hơn; từ các thử nghiệm trên một thiết lập khác, CTE đệ quy nhanh hơn một chút so với truy vấn phân cấp, nhưng điều đó có thể phụ thuộc vào tình huống cụ thể. CŨNG CÓ:CTE đệ quy chỉ hoạt động trong Oracle 11.2 trở lên; giải pháp phân cấp hoạt động với các phiên bản cũ hơn.

Tôi đã thêm một chút dữ liệu thử nghiệm để khớp với Anatoliy's.

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. Bảng kiểm tra Oracle Trigger cơ bản

  2. Oracle PL / SQL:Động lặp lại các cột kích hoạt

  3. truy vấn để tìm tất cả các cột trong bảng không có giá trị trong đó

  4. oci_bind_by_name để làm gì?

  5. Phân tích cú pháp tên bảng từ một loạt câu lệnh SQL