2011-09-15 19 views
8

Tôi có kết nối bằng truy vấn trước để xây dựng cấu trúc cây của tôi trong Oracle. Điều này làm việc tốt, nhưng tôi có một thành phần đòi hỏi một cây đối xứng để hiển thị chính xác.Kết nối bằng cây trước phải đối xứng

Vì vậy, ý tưởng của tôi là thêm nhiều nút vào cây nếu nút nằm trên một mức thấp hơn mức cao nhất.

ví dụ: nếu chúng ta có một cây

Root 
    +- Node 1 
    +- Leaf 1 (Level 3) 
    +- Node 2 
    +- Node 3 
     +- Leaf 2 (Level 4) 

Tôi cần phải sửa đổi các cây trong thời gian chạy trông như thế này:

Root 
    +- Node 1 
    +- Copy of Node 1 
     +- Leaf 1 (Level 4) 
    +- Node 2 
    +- Node 3 
     +- Leaf 2 (Level 4) 

này sẽ làm cho cây của tôi đối xứng trong thời gian chạy cho các thành phần để làm việc.

Có một truy vấn hoặc chức năng Oracle dễ dàng có thể hỗ trợ điều này hay một số câu lệnh SQL có thể hỗ trợ điều này không?

Trả lời

0

Tôi không nghĩ rằng nó có thể được thực hiện trong SQL, hoặc ít nhất tôi không thể nghĩ ra một cách để làm điều đó. Dường như với tôi rằng truy vấn sẽ phải biết có bao nhiêu cấp độ mong đợi trước khi nó thực thi.

Có lẽ, sau đó, bạn cần một bảng tạm thời để bạn có thể thực hiện lần thứ hai trong logic của bạn để có được nó theo cách bạn muốn.

Bạn có thành phần phía máy khách sẽ hiển thị những dữ liệu này không? Nếu vậy thì đó có thể là nơi đơn giản nhất để thực hiện lần truyền thứ hai này.

1

Ok, sau rất nhiều dấu vết và lỗi, tôi nghĩ tôi đã tìm được giải pháp.

Vì vậy, nếu bạn có bảng thử nghiệm, hãy gọi xx_tree_test với 3 trường: cd, sup_cd và name; và tôi thêm các dữ liệu thử nghiệm với nó, truy vấn này

 SELECT CD, 
      SUP_CD, 
      LEVEL AS LVL, 
      CASE WHEN CONNECT_BY_ISLEAF = 1 THEN 'L' ELSE NULL END AS LEAF, 
      LPAD (' ', 3 * LEVEL, ' .') || NAME AS NAME 
     FROM xx_tree_test 
     START WITH SUP_CD IS NULL 
     CONNECT BY PRIOR CD = SUP_CD; 

sẽ mang lại kết quả này:

enter image description here

Để thêm nút thêm để mang lá 1 và lá 2 để cùng cấp bạn cần truy vấn này:

SELECT CD, 
      SUP_CD, 
      LEVEL AS LVL, 
      CASE WHEN CONNECT_BY_ISLEAF = 1 THEN 'L' ELSE NULL END AS LEAF, 
      LPAD (' ', 3 * LEVEL, ' .') || NAME AS NAME   
     FROM (WITH FULL_TREE 
       AS ( SELECT CD, 
           SUP_CD, 
           LEVEL AS LVL, 
           CASE 
            WHEN CONNECT_BY_ISLEAF = 1 THEN 'L' 
            ELSE NULL 
           END 
            AS LEAF, 
           LPAD (' ', 3 * LEVEL, ' .') || NAME AS TREE_NAME, 
           NAME 
          FROM XX_TREE_TEST 
        START WITH SUP_CD IS NULL 
        CONNECT BY PRIOR CD = SUP_CD) 
      SELECT A.NAME, 
        A.CD, 
        A.SUP_CD, 
        A.LVL 
       FROM FULL_TREE A 
      WHERE NVL (LEAF, 'z') != 'L' 
      UNION ALL 
      SELECT CASE 
         WHEN TREE1.LVL + TREE2.ROW_NUM_GENERATED - 1 = 
           (SELECT MAX (LVL) FROM FULL_TREE) 
         THEN 
         TREE1.NAME 
         ELSE 
         'Copy of ' || TREE1.NAME 
        END 
         AS NAME, 
        CASE 
         WHEN TREE1.LVL + TREE2.ROW_NUM_GENERATED - 1 = 
           (SELECT MAX (LVL) FROM FULL_TREE) 
         THEN 
         CD 
         ELSE 
         CD || '`' || TO_CHAR (TREE2.ROW_NUM_GENERATED) 
        END 
         AS CD, 
        CASE 
         WHEN TREE2.ROW_NUM_GENERATED = 1 THEN SUP_CD 
         ELSE CD || '`' || TO_CHAR (TREE2.ROW_NUM_GENERATED - 1) 
        END 
         AS SUP_CD, 
        TREE1.LVL + TREE2.ROW_NUM_GENERATED AS LVL 
       FROM (SELECT FULL_TREE.NAME, 
           FULL_TREE.CD, 
           FULL_TREE.SUP_CD, 
           FULL_TREE.LVL 
         FROM FULL_TREE 
         WHERE LEAF = 'L') TREE1 
        JOIN 
         ( SELECT LEVEL AS ROW_NUM_GENERATED 
          FROM DUAL 
         CONNECT BY LEVEL <= (SELECT MAX (LVL) FROM FULL_TREE)) TREE2 
        ON (SELECT MAX (LVL) FROM FULL_TREE) + 1 >= 
         TREE2.ROW_NUM_GENERATED + TREE1.LVL 
      ORDER BY CD, LVL) 
START WITH SUP_CD IS NULL 
CONNECT BY PRIOR CD = SUP_CD; 

Không có truy vấn này sẽ mang lại kết quả này:

enter image description here

Vì vậy, tất cả những gì cần làm bây giờ chỉ là gói nó vào một giao diện đẹp để ẩn số lượng lớn SQL.

Các vấn đề liên quan