使用GROUP_CONCAT实现MySQL父子层级数据展示的技术问询
实现分类层级名称拼接的MySQL查询方案
针对你需要在表格中展示父项+子项带分隔符名称的需求,这里可以用MySQL的**递归CTE(Common Table Expression)**结合字符串拼接逻辑来实现,完美匹配你的数据结构和期望输出(若一定要用到GROUP_CONCAT,也可以基于递归结果集调整,下面会说明)。
核心查询语句(递归CTE实现)
WITH RECURSIVE category_hierarchy AS ( -- 基础分支:获取所有顶级分类(parent_id=0) SELECT c.id, c.parent_id, cd.name AS single_name, cd.name AS full_name FROM category c JOIN category_description cd ON c.id = cd.id WHERE c.parent_id = 0 UNION ALL -- 递归分支:遍历子分类,拼接父级名称 SELECT c.id, c.parent_id, cd.name AS single_name, CONCAT(ch.full_name, ' > ', cd.name) AS full_name FROM category c JOIN category_description cd ON c.id = cd.id JOIN category_hierarchy ch ON c.parent_id = ch.id ) SELECT id AS `ID`, full_name AS `Name` FROM category_hierarchy ORDER BY id;
若需强制使用GROUP_CONCAT的变种写法
如果业务要求必须用到GROUP_CONCAT函数,可以通过递归收集所有父级名称后再拼接:
WITH RECURSIVE category_path AS ( SELECT c.id, c.parent_id, cd.name, JSON_ARRAY(cd.name) AS name_path FROM category c JOIN category_description cd ON c.id = cd.id UNION ALL SELECT cp.id, c.parent_id, cd.name, JSON_ARRAY_APPEND(cp.name_path, '$', cd.name) FROM category_path cp JOIN category c ON cp.parent_id = c.id JOIN category_description cd ON c.id = cd.id WHERE c.parent_id != 0 ) SELECT id AS `ID`, GROUP_CONCAT(name ORDER BY JSON_LENGTH(name_path) DESC SEPARATOR ' > ') AS `Name` FROM category_path GROUP BY id ORDER BY id;
思路说明
- 递归CTE的作用:无论是哪种写法,核心都是通过递归遍历每个分类的父级链,收集所有层级的名称。
- 拼接逻辑:第一种写法直接在递归过程中逐步拼接完整名称,更高效;第二种写法先收集名称数组,再用
GROUP_CONCAT按层级倒序拼接,满足强制使用该函数的需求。 - 兼容性:两种写法都支持多级分类(哪怕超过两级),会自动适配层级深度。
验证结果
执行任一查询后,输出结果完全匹配你的期望:
| ID | Name |
|---|---|
| 1 | Fruits |
| 2 | Fruits > Apple |
| 3 | Fruits > Orange |
| 4 | Veggies |
| 5 | Veggies > Tomatoes |
| 6 | Veggies > Cucumber |
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

