上一篇
假设你在管理一个电商平台的商品分类系统,分类结构是多层级的——电子产品"下面有"手机","手机"下面又有"苹果"和"安卓",这种父子关系的数据怎么在MySQL里优雅地查询和展示呢?特别是当你需要把多级分类名称拼接成完整路径时(如"电子产品 > 手机 > 苹果"),CONCAT
函数就是你的好帮手。
今天我们就来聊聊如何用MySQL处理父子关系数据,重点是通过CONCAT
实现层级拼接的技巧。
先建个简单的分类表,存储父子关系:
CREATE TABLE categories ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, parent_id INT NULL, FOREIGN KEY (parent_id) REFERENCES categories(id) );
插入一些示例数据:
INSERT INTO categories (name, parent_id) VALUES ('电子产品', NULL), ('手机', 1), ('苹果', 2), ('安卓', 2), ('笔记本电脑', 1), ('游戏本', 5), ('轻薄本', 5);
先查直接父子关系(比如查"手机"的子分类):
SELECT child.name AS child_name FROM categories parent JOIN categories child ON child.parent_id = parent.id WHERE parent.name = '手机';
结果:
+------------+
| child_name |
+------------+
| 苹果 |
| 安卓 |
+------------+
如果明确知道最多3级分类,可以硬编码拼接:
SELECT CONCAT( IFNULL(grandparent.name, ''), IF(grandparent.name IS NOT NULL, ' > ', ''), IFNULL(parent.name, ''), IF(parent.name IS NOT NULL, ' > ', ''), child.name ) AS full_path FROM categories child LEFT JOIN categories parent ON child.parent_id = parent.id LEFT JOIN categories grandparent ON parent.parent_id = grandparent.id WHERE child.name = '苹果';
结果:
+-----------------------+
| full_path |
+-----------------------+
| 电子产品 > 手机 > 苹果 |
+-----------------------+
MySQL 8.0+支持递归CTE,适合不确定层级的场景:
WITH RECURSIVE category_path AS ( -- 基础查询:找出目标节点(如'苹果') SELECT id, name, parent_id, name AS path FROM categories WHERE name = '苹果' UNION ALL -- 递归部分:向上查找父节点 SELECT c.id, c.name, c.parent_id, CONCAT(c.name, ' > ', cp.path) FROM categories c JOIN category_path cp ON c.id = cp.parent_id ) SELECT path FROM category_path ORDER BY LENGTH(path) DESC LIMIT 1;
结果:
+-----------------------+
| path |
+-----------------------+
| 电子产品 > 手机 > 苹果 |
+-----------------------+
用IFNULL
避免NULL值破坏拼接:
CONCAT( IFNULL(parent.name, ''), IF(parent.name IS NOT NULL, ' > ', ''), child.name )
有时需要从子节点回溯到根节点:
WITH RECURSIVE category_tree AS ( SELECT id, name, parent_id, name AS breadcrumb FROM categories WHERE name = '游戏本' UNION ALL SELECT c.id, c.name, c.parent_id, CONCAT(c.name, ' > ', ct.breadcrumb) FROM categories c JOIN category_tree ct ON c.id = ct.parent_id ) SELECT breadcrumb FROM category_tree WHERE parent_id IS NULL;
结果:
+----------------------------------+
| breadcrumb |
+----------------------------------+
| 电子产品 > 笔记本电脑 > 游戏本 |
+----------------------------------+
Q:CONCAT和CONCAT_WS有什么区别?
A:CONCAT_WS
会自动跳过NULL值并用指定分隔符连接,
CONCAT_WS(' > ', grandparent.name, parent.name, child.name)
Q:MySQL 5.7以下版本怎么实现递归?
A:需要存储过程或应用层代码处理,无法纯SQL优雅解决。
通过CONCAT
函数结合JOIN或递归CTE,可以灵活处理MySQL中的父子关系数据,关键点:
下次遇到商品分类、组织架构或评论回复这种层级数据时,试试这些方法吧!
本文由 魏白容 于2025-08-02发表在【云服务器提供商】,文中图片由(魏白容)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/518155.html
发表评论