首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 遞歸查詢實戰:START WITH ... CONNECT BY 核心語法與正反向遍歷

     編輯:Oracle 資料庫基礎

前言

樹形結構數據(組織架構、菜單、物料 BOM)在 Oracle 中常用 START WITH ... CONNECT BY 進行遞歸查詢。本文通過建表、插數、正向/反向遍歷示例,詳細講解核心子句語法、PRIOR 運算符位置決定遍歷方向、LEVEL 偽列、SYS_CONNECT_BY_PATH 路徑拼接等實戰技巧。

測試數據準備


CREATE TABLE tbl_test (
  id   NUMBER PRIMARY KEY,
  name VARCHAR2(100),
  pid  NUMBER DEFAULT 0
);

INSERT INTO tbl_test VALUES (1, '10', 0);
INSERT INTO tbl_test VALUES (2, '11', 1);
INSERT INTO tbl_test VALUES (3, '20', 0);
INSERT INTO tbl_test VALUES (4, '12', 1);
INSERT INTO tbl_test VALUES (5, '121', 2);
COMMIT;

樹形結構:

10 (root)
 ├─ 11
 │   └─ 121
 └─ 12
20 (root)

核心語法


SELECT column_list
FROM table_name
[WHERE condition]
[START WITH root_condition]
CONNECT BY [NOCYCLE] PRIOR parent_col = child_col
[ORDER SIBLINGS BY col];

正向遍歷:根 → 葉 (Top-Down)


SELECT id, name, pid, LEVEL, SYS_CONNECT_BY_PATH(name, '>') AS path
FROM tbl_test
START WITH id = 1
CONNECT BY PRIOR id = pid;

關鍵:PRIOR id = pid 表示「上一條記錄的 ID = 當前記錄的 PID」,即父 → 子。

結果:

IDNAMEPIDLEVELPATH
11001>10
21112>10>11
512123>10>11>121
41212>10>12

反向遍歷:葉 → 根 (Bottom-Up)


SELECT id, name, pid, LEVEL
FROM tbl_test
START WITH id = 5
CONNECT BY PRIOR pid = id;

關鍵:PRIOR pid = id 表示「上一條記錄的 PID = 當前記錄的 ID」,即子 → 父。

結果:

IDNAMEPIDLEVEL
512121
21112
11003

進階技巧

需求寫法
多根節點START WITH pid = 0 或 START WITH id IN (1,3)
過濾特定層級WHERE LEVEL <= 2 (在 CONNECT BY 後)
排序同級節點ORDER SIBLINGS BY name
檢測循環CONNECT BY NOCYCLE PRIOR ... + CONNECT_BY_ISCYCLE 偽列
路徑拼接SYS_CONNECT_BY_PATH(col, '/')
判斷葉子節點CONNECT_BY_ISLEAF 偽列 (1=葉子)

子查詢中使用遞歸 (反向收集祖先)


SELECT * FROM v_wf_wfkind_tree
WHERE id IN (
  SELECT DISTINCT id
  FROM v_wf_wfkind_tree
  START WITH id IN ('0','01','0101','0203','0304')
  CONNECT BY PRIOR pid = id
);

從給定節點集合向上遞歸收集所有祖先,配合去重獲取完整鏈路。

總結

掌握 START WITH 定根、CONNECT BY PRIOR 定向 (父→子 vs 子→父)、LEVEL/PATH/ISLEAF/ISCYCLE 偽列、ORDER SIBLINGS BY 排序,即可應對 99% 樹形查詢場景。11g+ 亦可用標準 WITH RECURSIVE (CTE) 實現跨庫兼容。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved