工作中(尤其是傳統專案中)常遇到這種需要,就是樹狀結構的查詢(多層查詢),常見的場景有:組織架構(使用者部門)查詢和多層選單查詢
例如,選單分為三級,一級選單、二級選單、三級選單,要求使用者依樹狀結構把各級選單查詢出來。如下圖所示
對於層級固定,層級數少的,一般3級,需求實作很簡單,先查詢最小子級,再依序查詢上級,最後再組裝回前端給前端就是了。
那麼問題來了,如果層級數很大,10級,或乾脆層級不確定,有的3級,有的5級,有的8級,與之前的層級固定,層級數相比,顯然問題更複雜了,我們來看看這種怎麼處理
這種情況,我們只需要一張表,就叫它樹形表吧:
CREATE TABLE tree ( id int not null auto_increment, name varchar(50) not null comment '名称', parent_id int not null default 0 comment '父级id', level int not null default 1 comment '层级,从1开始', created datetime, modified datetime );
三級查詢過程:查詢出三級tree, 根據三級tree的parent_id 查詢出二級tree, 同樣的方式再去查詢出一級tree, 後端組裝成樹狀數據,回前端。
這種情況,我們首先想到的就是子查詢或聯表查詢,但是肯本不能在實際開發中使用,原因大家都知道:
sql語句複雜,容易出錯
效能問題,可能會被領導幹
所以最好的方式就是,加一張表tree_depth,來維持層級深度關係。
CREATE TABLE tree_depth ( id int not null auto_increment, root_id int not null default 0 comment '根节点(祖先节点)id', tree_id int not null default 0 comment '当前节点id', depth int not null default 0 comment '深度(当前节点 tree_id 到 根节点 root_id 的深度)', created datetime );
表中depth 欄位表示的是: 目前節點tree_id 到根節點root_id 的深度,不是目前節點所在整個分支的深度,所有節點相對於自身的深度都是0
#有了tree_depth 表後,查詢一個N級節點的組織資料就方便了:
直接查tree 中所有level = 1 的節點,在出去這些節點的id 根據parent_id 去查下級節點, 查詢完所有的節點,就可以組裝成一個完整的樹狀圖回傳給前端
從tree 表查詢出節點treeNselect * from tree where id = N
根據treeN 的id 值,到tree_depth 表查詢出它的根節點id:select root_id from tree_depth where tree_id = #{treeId}
根據root_id 查詢tree_depth 的所有目前節點分支資料select * from tree_depth where root_id = #{rootId}
從查詢出tree_depth 表資料中取出所有目前節點tree_id#select * from tree where id in (?,?,?)
#組裝所在分支樹狀結構
以上是MySql多層選單查詢怎麼實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!