Mysql實現(xiàn)遞歸樹查詢的使用示例
大家好! 在我們?nèi)粘9ぷ髦?,?jīng)常會遇到一些問題,它們的一些解決方案通常會用到遞歸這一強大的技術(shù)手段。遞歸不僅能幫助我們更高效的解決問題,還可以使代碼更簡介、更易于理解, 今天我來給大家分享如何在實際工作中使用mysql8+實現(xiàn)遞歸
Tip !!! 需要Mysql 8+上的版本支持
在大型組織中,理解員工建的層級關(guān)系至關(guān)重要。無論是管理、報告和策劃,一個清晰的組織層級視圖都是必不可少的。但是如何有效地從一個大型、復(fù)雜的員工數(shù)據(jù)庫中提取到這樣的層級信息呢?
遞歸執(zhí)行分析
mysql8+遞歸查詢的實現(xiàn)是基于 WITH RECURSIVE語句。它從一個初始的"基礎(chǔ)情況"開始,然后不斷的重復(fù)或"遞歸" 的一個連接操作,直到滿足某個條件為止。
以下是遞歸查詢的基本結(jié)構(gòu):
1. 基礎(chǔ)情況: 這是遞歸的起點,也就是根節(jié)點,在我們場景中根節(jié)點是CEO或者它的上級為null。
2. 遞歸情況: 基于基礎(chǔ)情況,查詢將繼續(xù)擴展,包括下一級的員工,然后類推。
WITH RECURSIVE hierarchy AS ( -- 基礎(chǔ)情況 ... UNION ALL -- 遞歸情況 ... ) select xxx from hierarchy
demo數(shù)據(jù)
模擬插入10w條數(shù)據(jù), 層級最高6層
DROP TABLE IF EXISTS employees; CREATE TABLE employees ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(100), manager_id INT, FOREIGN KEY (manager_id) REFERENCES employees(id) ); -- 新增根節(jié)點數(shù)據(jù) INSERT INTO employees (name) VALUES ('CEO'); -- 創(chuàng)建執(zhí)行過程 DELIMITER $$ CREATE PROCEDURE InsertLargeAmountOfData() BEGIN DECLARE id INT DEFAULT 2; DECLARE parentId INT DEFAULT 1; DECLARE counter INT DEFAULT 0; -- 第2層 WHILE counter < 10 DO INSERT INTO employees (name, manager_id) VALUES (CONCAT('L2-', id), 1); SET id = id + 1; SET counter = counter + 1; END WHILE; SET counter = 0; -- 第3層 WHILE counter < 100 DO SET parentId = 1 + FLOOR(counter / 10) + 1; INSERT INTO employees (name, manager_id) VALUES (CONCAT('L3-', id), parentId); SET id = id + 1; SET counter = counter + 1; END WHILE; SET counter = 0; -- 第4層 WHILE counter < 1000 DO SET parentId = 11 + FLOOR(counter / 100); INSERT INTO employees (name, manager_id) VALUES (CONCAT('L4-', id), parentId); SET id = id + 1; SET counter = counter + 1; END WHILE; SET counter = 0; -- 第5層 WHILE counter < 10000 DO SET parentId = 111 + FLOOR(counter / 1000); INSERT INTO employees (name, manager_id) VALUES (CONCAT('L5-', id), parentId); SET id = id + 1; SET counter = counter + 1; END WHILE; SET counter = 0; -- 第6層 WHILE counter < 88889 DO SET parentId = 1111 + FLOOR(counter / 10000); INSERT INTO employees (name, manager_id) VALUES (CONCAT('L6-', id), parentId); SET id = id + 1; SET counter = counter + 1; END WHILE; END$$ DELIMITER ; -- 執(zhí)行執(zhí)行過程 CALL InsertLargeAmountOfData();
查詢demo數(shù)據(jù)
WITH RECURSIVE hierarchy AS ( -- 基礎(chǔ)情況 select id,name,manager_id from employees where manager_id is null UNION ALL -- 遞歸情況 select e.* from employees as e inner join hierarchy as h on e.manager_id = h.id ) select id,name,manager_id from hierarchy
結(jié)果
在以上圖例中,通過調(diào)整manager_id is null 可以配置要查詢某條數(shù)據(jù)及該數(shù)據(jù)所有子數(shù)據(jù)的查詢出來的內(nèi)容。
??Tip! 查詢的結(jié)果將以列表形式展現(xiàn)。若業(yè)務(wù)代碼中需要完整的樹狀結(jié)構(gòu),可以在每個節(jié)點中關(guān)聯(lián)其上級節(jié)點。最后,通過取manager_id is null的記錄下的子節(jié)點數(shù)據(jù),即可得到完整的樹狀數(shù)據(jù)。
擴展
字段擴展
在業(yè)務(wù)中常常會需要查詢某條記錄并返回該字段在組織層次中的位置,你可以參考以下代碼:
WITH RECURSIVE hierarchy AS ( -- 基礎(chǔ)情況:從CEO開始 SELECT id, name, manager_id, CAST(name AS CHAR(255)) AS hierarchy_path FROM employees WHERE manager_id IS NULL UNION ALL -- 遞歸情況:為每個下級員工添加上級 SELECT e.id, e.name, e.manager_id, CONCAT(h.hierarchy_path, ' > ', e.name) FROM employees e JOIN hierarchy h ON e.manager_id = h.id ) SELECT id, name, manager_id, hierarchy_path FROM hierarchy -- 查詢某條數(shù)據(jù)條件 WHERE name = 'L3-111' ORDER BY id;
結(jié)果如下圖:
到此這篇關(guān)于Mysql實現(xiàn)遞歸樹查詢的使用示例的文章就介紹到這了,更多相關(guān)Mysql 遞歸樹查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL數(shù)據(jù)庫Event定時執(zhí)行任務(wù)詳解
這篇文章主要介紹了MySQL數(shù)據(jù)庫Event定時執(zhí)行任務(wù)2017-12-12通過存儲過程動態(tài)創(chuàng)建MySQL對象的流程步驟
在當今數(shù)據(jù)驅(qū)動的世界中,高效的數(shù)據(jù)庫管理至關(guān)重要,本文將展示如何通過存儲過程自動化地創(chuàng)建各種?MySQL?數(shù)據(jù)庫對象,通過這些方法,我們可以快速響應(yīng)業(yè)務(wù)需求,提高數(shù)據(jù)庫管理的靈活性和效率,需要的朋友可以參考下2024-10-10Mysql BinLog存儲機制與數(shù)據(jù)恢復(fù)方式
這篇文章主要介紹了Mysql BinLog存儲機制與數(shù)據(jù)恢復(fù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06MySQL操作數(shù)據(jù)庫和表的常用命令新手教程
這篇文章主要介紹了MySQL操作數(shù)據(jù)庫和表的常用命令新手教程,本文總結(jié)的命令都是控制mysql必須掌握的、常用的命令,需要的朋友可以參考下2014-09-09wampserver下mysql導(dǎo)入數(shù)據(jù)庫的步驟
這篇文章主要介紹了wampserver下mysql導(dǎo)入數(shù)據(jù)庫的步驟,需要的朋友可以參考下2016-08-08