| 欄位 | 說明 |
LEVEL | 當前層級(根=1) |
CONNECT_BY_ISLEAF | 1=葉節點, 0=非葉 |
CONNECT_BY_ROOT col | 根節點的 col 值 |
SYS_CONNECT_BY_PATH(col, '/') | 從根到當前節點的路徑字串 |
樹狀結構條件過濾:砍掉分支
錯誤寫法(在 WHERE 過濾會先過濾再遞迴,導致子孫遺失):
-- 錯誤:會遺失被過濾節點的所有子孫
SELECT * FROM org_industries
START WITH ind_id = 1
CONNECT BY parent_id = PRIOR ind_id
WHERE industry_name != '服裝'; -- 服裝及其子孫全消失
正確寫法(在 CONNECT BY 加條件,保留子孫但不顯示該節點):
SELECT * FROM org_industries
START WITH ind_id = 1
CONNECT BY parent_id = PRIOR ind_id
AND industry_name != '服裝'; -- 不顯示「服裝」,但其子孫仍會展開
進階:完全排除某分支(含子孫):
SELECT * FROM org_industries
START WITH ind_id = 1
CONNECT BY parent_id = PRIOR ind_id
AND PRIOR industry_name != '服裝'; -- 父節點不是「服裝」才繼續遞迴
遞迴 CTE(ANSI SQL 標準,11g R2+)
WITH RECURSIVE org_tree (ind_id, industry_name, parent_id, lvl, path) AS (
-- Anchor member
SELECT ind_id, industry_name, parent_id, 1, industry_name
FROM org_industries
WHERE ind_id = 1
UNION ALL
-- Recursive member
SELECT c.ind_id, c.industry_name, c.parent_id, p.lvl + 1,
p.path || ' > ' || c.industry_name
FROM org_industries c
JOIN org_tree p ON c.parent_id = p.ind_id
WHERE p.lvl < 20 -- 防無限遞迴
)
SELECT * FROM org_tree ORDER BY path;
優點:標準 SQL、可攜性高、易於除錯、支援複雜多欄位排序。
效能優化建議
- 為
parent_id、ind_id 建立索引。
- 大型樹狀表(>10萬筆)考慮
NOCYCLE 防循環:CONNECT BY NOCYCLE parent_id = PRIOR ind_id。
- 避免在遞迴查詢中使用非確定性函數(
SYSDATE, DBMS_RANDOM)。
- 僅需特定深度時,在 CTE 中加
WHERE lvl <= n 或 CONNECT BY ... AND LEVEL <= n。
常見應用範例
1. 組織架構圖(員工-主管)
SELECT LPAD(' ', 2*(LEVEL-1)) || ename AS org_chart,
empno, mgr, LEVEL
FROM emp
START WITH mgr IS NULL
CONNECT BY mgr = PRIOR empno;
2. 物料清單 (BOM) 總價計算
WITH RECURSIVE bom_calc (part_id, parent_id, qty, unit_cost, total_cost, lvl) AS (
SELECT part_id, parent_id, qty, unit_cost, qty * unit_cost, 1
FROM bom WHERE part_id = :root_part
UNION ALL
SELECT b.part_id, b.parent_id, b.qty, b.unit_cost,
p.total_cost * b.qty * b.unit_cost, p.lvl + 1
FROM bom b
JOIN bom_calc p ON b.parent_id = p.part_id
)
SELECT SUM(total_cost) FROM bom_calc;
結語
掌握 CONNECT BY 與遞迴 CTE 兩套語法,並理解 START WITH、CONNECT BY、WHERE 三者的執行順序差異,是處理 Oracle 樹狀資料的關鍵。新專案建議優先使用遞迴 CTE,符合 ANSI 標準且更易維護。
- 上一篇文章: Windows 環境下徹底移除 Oracle 服務與殘留元件的標準流程
- 下一篇文章: Oracle PL/SQL 中修改 Collection 參數的關鍵技巧:IN OUT 模式詳解
Copyright ©
程式碼之家 All Rights Reserved