MySQL树形结构查询 SQL语句详解

1. 引言

在关系型数据库中,树形结构是一种常见的数据结构,在处理层级关系的数据时非常有用。在MySQL中,我们可以使用SQL语句来查询和操作树形结构的数据。本文将详细介绍如何使用SQL查询和操作MySQL中的树形结构数据,并给出相应的代码示例。

2. 树形结构示例

假设我们有一个名为"categories"的表,用于存储商品分类信息。该表包含以下字段:

  • id:分类ID,主键
  • name:分类名称
  • parent_id:父级分类ID

通过parent_id字段,我们可以建立商品分类之间的层级关系,形成一个树形结构。下面是一个示例的分类数据:

id name parent_id
1 电子产品 NULL
2 手机 1
3 电脑 1
4 家用电器 1
5 苹果手机 2
6 华为手机 2
7 台式电脑 3
8 笔记本电脑 3
9 空调 4
10 冰箱 4

从上表中可以看出,分类ID为1的分类是顶级分类,其他分类都是其子分类。分类ID为2的分类是分类ID为1的分类的子分类,以此类推。

3. 查询子分类

查询某个分类的所有子分类,可以使用递归查询的方式。MySQL中可以使用WITH RECURSIVE关键字来实现递归查询。下面是一个查询分类ID为1的分类及其所有子分类的SQL语句示例:

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id
  FROM categories
  WHERE id = 1
  UNION ALL
  SELECT c.id, c.name, c.parent_id
  FROM categories c
  INNER JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree;

上述代码中,首先定义了一个递归查询的公共表达式category_tree,并指定初始查询条件为id = 1的分类。然后使用UNION ALL将初始查询结果与后续的递归查询结果进行合并。在递归查询中,通过INNER JOIN将当前查询结果与categories表进行连接,连接条件为parent_id等于上一层查询结果的id。递归查询将一直进行,直到没有满足连接条件的数据为止。

运行上述SQL语句,将会返回分类ID为1的分类及其所有子分类的数据。

4. 查询父分类

查询某个分类的父分类,也可以使用递归查询的方式。下面是一个查询分类ID为5的分类及其所有父分类的SQL语句示例:

WITH RECURSIVE category_tree AS (
  SELECT id, name, parent_id
  FROM categories
  WHERE id = 5
  UNION ALL
  SELECT c.id, c.name, c.parent_id
  FROM categories c
  INNER JOIN category_tree ct ON c.id = ct.parent_id
)
SELECT * FROM category_tree;

与查询子分类类似,上述代码中也使用了WITH RECURSIVE关键字来实现递归查询。不同的是,在递归查询中使用INNER JOIN将当前查询结果与categories表进行连接,连接条件为id等于上一层查询结果的parent_id。

运行上述SQL语句,将会返回分类ID为5的分类及其所有父分类的数据。

5. 查询分类路径

查询某个分类的完整路径,即从顶级分类到该分类的所有父分类。下面是一个查询分类ID为5的分类的完整路径的SQL语句示例:

WITH RECURSIVE category_path AS (
  SELECT id, name, parent_id, CAST(name AS CHAR(200)) AS path
  FROM categories
  WHERE id = 5
  UNION ALL
  SELECT c.id, c.name, c.parent_id, CONCAT(cp.path, ' > ', c.name)