| 偽欄位 | 用途 |
LEVEL | 節點層級,根為 1,子節點遞增。 |
CONNECT_BY_ISCYCLE | 該節點是否導致循環(1=是,0=否)。 |
CONNECT_BY_ISLEAF | 是否為葉節點(1=是,0=否)。 |
SYS_CONNECT_BY_PATH(col, '/') | 從根到目前節點的路徑字串。 |
實戰範例(HR.EMPLOYEES)
1. 基本上下層關係
SELECT employee_id, last_name, manager_id
FROM employees
CONNECT BY PRIOR employee_id = manager_id;
2. 顯示層級
SELECT employee_id, last_name, manager_id, LEVEL
FROM employees
CONNECT BY PRIOR employee_id = manager_id;
3. 指定根節點 + 同層排序
SELECT last_name, employee_id, manager_id, LEVEL
FROM employees
START WITH employee_id = 100 -- King
CONNECT BY PRIOR employee_id = manager_id
ORDER SIBLINGS BY last_name;
4. 處理循環參考 (NOCYCLE)
將 Russell 設為 King 的主管,製造循環:
UPDATE employees SET manager_id = 145 WHERE employee_id = 100;
SELECT last_name "Employee", CONNECT_BY_ISCYCLE "Cycle",
LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') "Path"
FROM employees
WHERE LEVEL <= 3 AND department_id = 80
START WITH last_name = 'King'
CONNECT BY NOCYCLE PRIOR employee_id = manager_id AND LEVEL <= 4;
結果會標記 Cycle=1 的節點(Russell),並繼續展開其他分支。
5. CONNECT_BY_ROOT 取得根節點資訊
-- 110 部門員工與其各層級主管
SELECT last_name "Employee",
CONNECT_BY_ROOT last_name "Root_Manager",
LEVEL-1 "Path_Len",
SYS_CONNECT_BY_PATH(last_name, '/') "Path"
FROM employees
WHERE LEVEL > 1 AND department_id = 110
CONNECT BY PRIOR employee_id = manager_id;
6. 彙總根節點下所有子節點薪資
SELECT name, SUM(salary) "Total_Salary"
FROM (
SELECT CONNECT_BY_ROOT last_name AS name, salary
FROM employees
WHERE department_id = 110
CONNECT BY PRIOR employee_id = manager_id
)
GROUP BY name;
效能與使用建議
- 大量資料建立索引於
PRIOR 參考欄位(如 EMPLOYEE_ID、MANAGER_ID)。
- 避免在
CONNECT BY 條件中使用複雜函數或子查詢。
- 10g+ 推薦使用
CONNECT BY NO FILTERING(對應 Hint NO_CONNECT_BY_FILTERING)改善大樹狀結構效能。
- 搭配
START WITH 限制掃描範圍,避免全表遞迴。
- 上一篇文章: Oracle 自訂函數效能實測:引擎切換成本與實作差異分析
- 下一篇文章: PL/SQL 呼叫 Web Service 實作:UTL_DBWS 套件完整教學
Copyright ©
程式碼之家 All Rights Reserved