一篇文章學(xué)會(huì)SQL中的遞歸用法(Mysql)
1. SQL遞歸概念:
SQL遞歸查詢是一種用于處理具有層次結(jié)構(gòu)的數(shù)據(jù)的技術(shù)。它使用遞歸函數(shù)來(lái)遍歷樹(shù)形結(jié)構(gòu),例如組織結(jié)構(gòu)、分類結(jié)構(gòu)等等。
遞歸查詢通常使用 " WITH RECURSIVE " 語(yǔ)句實(shí)現(xiàn)。
WITH RECURSIVE 語(yǔ)句包含兩部分:
a.遞歸部分: 定義了如何遞歸查詢數(shù)據(jù);
b.終止條件部分: 定義了遞歸查詢何時(shí)停止。
2. SQL遞歸一般形式:
WITH RECURSIVE recursive_query_name (col1, col2, ..., coln) AS (
-- 遞歸部分
SELECT
initial_query_result_col1,
initial_query_result_col2,
...,
initial_query_result_coln
FROM initial_query
UNION ALL
SELECT
recursive_query_result_col1,
recursive_query_result_col2,
...,
recursive_query_result_coln
FROM recursive_query_name, recursive_query
WHERE recursive_query_condition
)
-- 終止條件部分
SELECT * FROM recursive_query_name WHERE termination_condition;
在遞歸部分,我們先通過(guò)一個(gè)初始查詢(initial_query)得到一些初始的結(jié)果。然后我們通過(guò)UNION ALL運(yùn)算將初始結(jié)果集合并到遞歸查詢結(jié)果中。接下來(lái),在每次遞歸查詢中,我們使用前一次遞歸的結(jié)果(recursive_query_name)與遞歸查詢(recursive_query)進(jìn)行運(yùn)算,并使用WHERE條件過(guò)濾掉不需要的數(shù)據(jù)。最后,在終止條件部分中,我們使用一個(gè)條件來(lái)判斷遞歸查詢何時(shí)停止。當(dāng)遞歸查詢到終止條件時(shí),遞歸查詢結(jié)束,最終結(jié)果被返回。
3. SQL遞歸優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
- 靈活性:SQL遞歸查詢適用于各種類型的樹(shù)形結(jié)構(gòu),而且可以根據(jù)具體的需要自定義遞歸查詢算法。
- 可讀性:遞歸查詢通常比使用嵌套查詢或連接查詢更易于閱讀和理解。它可以用簡(jiǎn)單的SQL語(yǔ)句來(lái)表示一個(gè)復(fù)雜的樹(shù)形結(jié)構(gòu)。
- 便于維護(hù):SQL遞歸查詢通常比其他方法更易于維護(hù)。例如,如果要更改樹(shù)形結(jié)構(gòu)中的某些節(jié)點(diǎn),只需更改遞歸查詢算法即可。
缺點(diǎn):
- 性能:SQL遞歸查詢通常比其他方法慢。這是因?yàn)樗枰M(jìn)行多次遞歸函數(shù)調(diào)用,并且可能需要訪問(wèn)大量的數(shù)據(jù)。如果不正確地編寫(xiě)遞歸查詢算法,還可能會(huì)導(dǎo)致死循環(huán)等問(wèn)題,從而影響性能。
- 復(fù)雜性:遞歸查詢算法通常比其他方法更復(fù)雜。如果不熟悉遞歸算法,編寫(xiě)正確的遞歸查詢算法可能很困難。
- 可伸縮性:SQL遞歸查詢不適合處理大型數(shù)據(jù)集。當(dāng)數(shù)據(jù)集變得太大時(shí),查詢可能會(huì)變得非常緩慢,甚至無(wú)法運(yùn)行。
總體而言,SQL遞歸查詢是一種非常有用的技術(shù),可以處理樹(shù)形結(jié)構(gòu)的數(shù)據(jù)。雖然它具有一些缺點(diǎn),但在正確使用的情況下,它仍然是一種非常強(qiáng)大和靈活的工具。
4.案例:公司部門關(guān)系遞歸查詢
a.按DDL建表:
CREATE TABLE company_department (
department_id INT PRIMARY KEY,
department_name VARCHAR(50),
parent_department_id INT REFERENCES company_department(department_id)
);b.插入數(shù)據(jù):
INSERT INTO company_department
(department_id, department_name, parent_department_id)
VALUES
(1, '公司', NULL),
(2, '人力資源部', 1),
(3, '財(cái)務(wù)部', 1),
(4, '市場(chǎng)部', 1),
(5, '技術(shù)部', 1),
(6, '招聘部', 2),
(7, '薪資部', 2),
(8, '成本控制部', 3),
(9, '收支管理部', 3),
(10, '品牌推廣部', 4),
(11, '銷售部', 4),
(12, '前端開(kāi)發(fā)部', 5),
(13, '后端開(kāi)發(fā)部', 5)c.遞歸查詢公司部門關(guān)系SQL語(yǔ)句
WITH RECURSIVE department_tree (department_id, department_name, parent_department_id, depth, path) AS ( SELECT department_id, department_name, parent_department_id, 1 AS depth, CAST(department_id AS CHAR(200)) AS path FROM company_department WHERE parent_department_id IS NULL UNION ALL SELECT cd.department_id, cd.department_name, cd.parent_department_id, dt.depth + 1 AS depth, CONCAT(dt.path, ',', cd.department_id) AS path FROM company_department cd JOIN department_tree dt ON cd.parent_department_id = dt.department_id ) SELECT department_id, department_name, parent_department_id, depth, path FROM department_tree ORDER BY path;
d.sql案例詳解:
這個(gè)查詢使用了遞歸公共表達(dá)式來(lái)遍歷公司部門關(guān)系。公共表達(dá)式使用了兩個(gè) SELECT 語(yǔ)句:
第一個(gè) SELECT 語(yǔ)句選取了所有沒(méi)有父部門的根部門,并將它們添加到臨時(shí)表
department_tree中。它們的深度被初始化為 1,并且它們的路徑被設(shè)置為它們的部門 ID。這個(gè) SELECT 語(yǔ)句是遞歸查詢的起點(diǎn)。第二個(gè) SELECT 語(yǔ)句連接了
company_department表和department_tree表。它選取了company_department表中所有具有父部門的部門,并連接到department_tree表中已經(jīng)存在的部門。對(duì)于每個(gè)連接的行,它們的深度是父部門的深度加 1,并且它們的路徑是父部門的路徑加上逗號(hào)和它們自己的部門 ID。查詢返回了
department_tree表中所有的部門,按照它們的路徑排序。這個(gè)排序方法使得在結(jié)果集中,每個(gè)部門都在它們的父部門之后,并且它們的順序是深度優(yōu)先遍歷的順序。
e.查詢結(jié)果截圖:

總結(jié)
到此這篇關(guān)于SQL中遞歸用法(Mysql)的文章就介紹到這了,更多相關(guān)SQL遞歸用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mySQL服務(wù)器連接,斷開(kāi)及cmd使用操作
這篇文章主要介紹了mySQL服務(wù)器連接,斷開(kāi)及cmd使用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
mysql分區(qū)表的增刪改查的實(shí)現(xiàn)示例
增刪查改在數(shù)據(jù)庫(kù)中是很常見(jiàn)的操作,本文主要介紹了mysql分區(qū)表的增刪改查的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01
mysql 連接出現(xiàn)Public Key Retrieval is n
在MySQL連接中出現(xiàn)“Public Key Retrieval is not allowed”錯(cuò)誤,通常是因?yàn)樵谑褂冒踩捉幼謱樱⊿SL)連接時(shí)遇到了問(wèn)題,本文就來(lái)介紹一下解決方法,感興趣的可以了解一下2024-03-03
MySQL進(jìn)行表之間關(guān)聯(lián)更新的實(shí)現(xiàn)方法
在實(shí)際編程工作或運(yùn)維實(shí)踐中,對(duì)MySQL數(shù)據(jù)庫(kù)表進(jìn)行關(guān)聯(lián)更新是一種比較常見(jiàn)的應(yīng)用場(chǎng)景,針對(duì)這樣的業(yè)務(wù)場(chǎng)景,我們來(lái)看看有什么方法可以實(shí)現(xiàn)關(guān)聯(lián)更新,需要的朋友可以參考下2023-10-10
MYSQL必知必會(huì)讀書(shū)筆記第十和十一章之使用函數(shù)處理數(shù)據(jù)
這篇文章主要介紹了MYSQL必知必會(huì)讀書(shū)筆記第十和十一章之使用函數(shù)處理數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2016-05-05
MySQL 5.7臨時(shí)表空間如何玩才能不掉坑里詳解
這篇文章主要給大家介紹了關(guān)于MySQL 5.7臨時(shí)表空間如何玩才能不掉坑里的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mysql具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧2018-09-09

