SQL語句中實現(xiàn)遞歸查詢操作方法
在SQL中實現(xiàn)遞歸查詢操作,通常有兩種主要的方法:使用遞歸公用表表達(dá)式(Recursive Common Table Expressions,CTEs)和遞歸查詢函數(shù)(例如,在PostgreSQL中使用WITH RECURSIVE,在SQL Server中使用WITH RECURSIVE或CTE,而在Oracle中使用CONNECT BY)。
數(shù)據(jù)表定義:
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
manager_id INT -- 指向上級,CEO的manager_id為NULL(或0,通常用NULL表示無上級)
);初始化數(shù)據(jù):
INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (101, '馬總', NULL); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (201, '張工', 101); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (202, '王工', 101); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (301, '李工', 201); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (401, '趙工', 301); INSERT INTO `employees` (`id`, `name`, `manager_id`) VALUES (402, '劉工', 301);
查詢需求:
請查詢出id=101的人員及其所有的下級信息(包括間接下級),同時標(biāo)記出下屬層級,自身層級設(shè)為0;
查詢語句(MySQL 8.0+):
要查詢 id = 101 的所有下級(包括直接和間接下級),并標(biāo)記出每個下屬所處的層級(1 表示直接下級,2 表示下級的下級,依此類推),可以使用遞歸公用表表達(dá)式(Recursive CTE)。以下是符合要求的 SQL 語句:
WITH RECURSIVE subordinates AS (
-- 初始查詢:找到直接下級(manager_id = 101)
SELECT
id,
name,
manager_id,
0 AS level
FROM employees
WHERE id = 101
UNION ALL
-- 遞歸查詢:找到下一級下屬
SELECT
e.id,
e.name,
e.manager_id,
s.level + 1
FROM employees e
INNER JOIN subordinates s ON e.manager_id = s.id
)
SELECT *
FROM subordinates
ORDER BY level, id;執(zhí)行結(jié)果:

語法解釋:
WITH RECURSIVE subordinates AS (...) 是 SQL 中用于定義遞歸公用表表達(dá)式(Recursive Common Table Expression)的語法。下面逐部分解釋:
1.WITH關(guān)鍵字
- 表示定義一個公用表表達(dá)式(CTE,Common Table Expression),類似于一個臨時的命名結(jié)果集,可以在后續(xù)的查詢中引用。
- 通常用于簡化復(fù)雜查詢,提高可讀性。
2.RECURSIVE關(guān)鍵字
- 指明該 CTE 是遞歸的,即它可以在自己的定義中引用自身,從而實現(xiàn)迭代或?qū)哟伪闅v。
- 大部分主流數(shù)據(jù)庫(如 PostgreSQL、MySQL 8.0+、SQL Server、Oracle)都支持該語法,但 MySQL 中必須明確寫出
RECURSIVE,而 SQL Server 中可省略(但需要其他方式表示遞歸)。
3.subordinates– CTE 名稱(自定義)
- 給這個臨時結(jié)果集取名為
subordinates,后續(xù)的SELECT語句就可以像使用普通表一樣使用它。
4. 括號內(nèi)的遞歸定義
遞歸 CTE 通常由兩部分組成,用 UNION ALL 連接:
(1)錨點成員(非遞歸部分)
SELECT id, name, manager_id, 1 AS level FROM employees WHERE id = 101
- 這是遞歸的起點,首先查詢出
id = 101的員工(即 101 自身)。 - 這里手動標(biāo)記
level = 0,表示第 0 層級。 - 錨點成員只執(zhí)行一次,其結(jié)果集作為遞歸的初始數(shù)據(jù)。
(2)遞歸成員(遞歸部分)
SELECT e.id, e.name, e.manager_id, s.level + 1 FROM employees e INNER JOIN subordinates s ON e.manager_id = s.id
- 遞歸成員會反復(fù)執(zhí)行,直到不再返回新行。
- 每次迭代中,它只將上一輪
subordinates結(jié)果集中的每一行(作為上級s)與employees表連接,找出這些上級的下級員工(e.manager_id = s.id)。 - 同時,層級別為
s.level + 1,表示比上一級深一層。 - 新找到的行被加入
subordinates結(jié)果集,并用于下一次迭代。
(3) 終止條件
- 當(dāng)某次迭代沒有產(chǎn)生任何新行時,遞歸自動停止。
- 要求數(shù)據(jù)中沒有循環(huán)引用(例如 A 的上級是 B,B 的上級又是 A),否則可能導(dǎo)致無限遞歸。大多數(shù)數(shù)據(jù)庫默認(rèn)設(shè)置了遞歸深度限制(如 MySQL 的
cte_max_recursion_depth)。
5. 最終引用
定義完 subordinates 后,外層的 SELECT * FROM subordinates 將返回所有遞歸收集到的行。
示例執(zhí)行流程
假設(shè) employees 表有數(shù)據(jù):
- id=101 管理 201,202
- 201 管理 301
- 301 管理 401,402
執(zhí)行過程:
- 錨點:找到 201、202,level=1。
subordinates當(dāng)前有 (201, ..., 1), (202, ..., 1)。- 第一次遞歸:以 201、202 為上級找下級 → 找到 301(上級 201),level=2。
subordinates新增 (301, ..., 2)。- 第二次遞歸:以 301 為上級找下級 → 找到 401,402,level=3。
subordinates新增 (401, ..., 3),(402, ..., 3)。- 第三次遞歸:以 401、402 為上級找下級 → 無結(jié)果,終止。
- 最終輸出所有行。
適用場景
- 組織架構(gòu)(上級-下級)
- 物料清單(BOM)
- 樹形結(jié)構(gòu)遍歷(評論回復(fù)、分類層級)
- 圖或路徑查詢
WITH RECURSIVE 是處理此類分層或遞歸查詢的標(biāo)準(zhǔn) SQL 方法,比使用游標(biāo)或多次自連接更加簡潔高效。
到此這篇關(guān)于SQL語句中如何實現(xiàn)遞歸查詢操作的文章就介紹到這了,更多相關(guān)SQL遞歸查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL實現(xiàn)篩選出連續(xù)3天登錄用戶與窗口函數(shù)的示例代碼
本文主要介紹了SQL實現(xiàn)篩選出連續(xù)3天登錄用戶與窗口函數(shù)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04
Sql注入工具_(dá)動力節(jié)點Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了Sql注入工具的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
SQL Server 2008 R2數(shù)據(jù)庫遷移的實現(xiàn)方法
這篇文章給大家介紹了SQL Server 2008 R2數(shù)據(jù)庫遷移的兩種方案簡要指南,文章通過圖文結(jié)合介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的小伙伴跟著小編一起來看看吧2024-01-01
sql server學(xué)習(xí)基礎(chǔ)之內(nèi)存初探
這篇文章主要給大家介紹了關(guān)于sql server中內(nèi)存的相關(guān)資料,文中通過圖文以及示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者理解sql server具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
sqlserver性能優(yōu)化之內(nèi)存優(yōu)化詳解
本文介紹了SQL Server內(nèi)存優(yōu)化的詳細(xì)方案,包括核心配置、監(jiān)控手段和高級技術(shù),并提供了腳本示例及配置建議,內(nèi)容涵蓋了內(nèi)存上下限設(shè)置、啟用AWE、緩沖池擴(kuò)展、監(jiān)控關(guān)鍵內(nèi)存指標(biāo)、清理緩存策略、索引優(yōu)化、內(nèi)存優(yōu)化表(In-Memory OLTP)以及自動化維護(hù)與監(jiān)控等2026-03-03

