在web應(yīng)用程序中,經(jīng)常需要進(jìn)行無限級別的分類,例如商城的商品分類,新聞的分類,菜單的分類等等。在這些分類中,通常都是可以進(jìn)行無限級別嵌套的。在mysql中,我們可以使用遞歸技術(shù)來實(shí)現(xiàn)這種無限級別的嵌套查詢。
WITH RECURSIVE cte(id, name, parent_id, level) AS ( SELECT id, name, parent_id, 0 FROM category WHERE parent_id IS NULL UNION ALL SELECT c.id, c.name, c.parent_id, level+1 FROM category c JOIN cte ON cte.id = c.parent_id ) SELECT id, name, parent_id, level FROM cte;
上面的代碼通過WITH RECURSIVE關(guān)鍵字來實(shí)現(xiàn)遞歸查詢。在cte(Common Table Expression)子句中,首先查詢出父級為NULL的節(jié)點(diǎn),即一級分類。然后利用UNION ALL將查詢結(jié)果與子節(jié)點(diǎn)查詢結(jié)果連接起來,連接條件為子節(jié)點(diǎn)的parent_id與父節(jié)點(diǎn)的id相同,這樣就實(shí)現(xiàn)了遞歸查詢出所有的子節(jié)點(diǎn)。
在查詢中,我們可以根據(jù)需要選擇需要的字段,例如上述代碼中查詢了id、name、parent_id和level四個(gè)字段。其中l(wèi)evel字段表示當(dāng)前節(jié)點(diǎn)的級別。如果我們只需要查詢出二級分類,可以使用where level<= 1來限制級別。
WITH RECURSIVE cte(id, name, parent_id, level) AS ( SELECT id, name, parent_id, 0 FROM category WHERE parent_id IS NULL UNION ALL SELECT c.id, c.name, c.parent_id, level+1 FROM category c JOIN cte ON cte.id = c.parent_id ) SELECT id, name, parent_id, level FROM cte WHERE level<= 1;
無限級別嵌套查詢在實(shí)現(xiàn)分類等功能時(shí)非常常見,掌握遞歸查詢可以方便解決這類問題。但是,在使用遞歸查詢時(shí),需要注意數(shù)據(jù)表的設(shè)計(jì)是否合理,過深的分類層級在實(shí)際應(yīng)用中可能會(huì)帶來效率問題。