📜  mysql 5.6 分层递归查询 - SQL (1)

📅  最后修改于: 2023-12-03 15:17:45.568000             🧑  作者: Mango

MySQL 5.6 分层递归查询 - SQL

在 MySQL 数据库中,有时需要进行分层递归查询。这种查询场景在组织架构管理、分类目录等场景中比较常见。本文介绍如何使用 MySQL 5.6 实现分层递归查询。

实现思路

在 MySQL 5.6 及以下版本中,没有提供递归查询的专用语法。但可以通过自连接、变量和存储过程等手段实现分层递归查询。

实现步骤如下:

  1. 创建一个临时表,存储递归查询中间结果。
  2. 定义一个存储过程,在其中实现递归查询,并将结果存储在临时表中。
  3. 调用存储过程,获取递归查询结果。
示例代码

以下代码示例实现了一个查询指定分类 ID 下的所有子分类的 SQL。假设有一个商品分类表 category,其中包含分类 ID 和上级分类 ID,查询某个分类下的所有子分类可使用如下 SQL:

-- 创建存储过程
DROP PROCEDURE IF EXISTS `getSubCategories`;
DELIMITER $$
CREATE PROCEDURE `getSubCategories`(IN categoryId INT)
BEGIN
    DECLARE subCategoryId INT;
    CREATE TEMPORARY TABLE IF NOT EXISTS temp_result(
        id INT NOT NULL
    );
    INSERT INTO temp_result (id) VALUES (categoryId);
    REPEAT
        SELECT id INTO subCategoryId FROM temp_result WHERE id NOT IN (
            SELECT IFNULL(parent_id, 0) FROM temp_result 
        ) LIMIT 1;
        IF subCategoryId IS NOT NULL THEN
            INSERT INTO temp_result (id) 
            SELECT id FROM category WHERE parent_id=subCategoryId;
        END IF;
    UNTIL subCategoryId IS NULL END REPEAT;
    SELECT * FROM temp_result;
END$$
DELIMITER ;

-- 调用存储过程
CALL getSubCategories(1);

该 SQL 中使用了 REPEAT-UNTIL 循环,实现了递归查询。首先将指定分类 ID 插入到临时表 temp_result 中,然后循环执行以下操作:

  1. 查询临时表中未处理的分类 ID,作为子分类 ID。
  2. 如果子分类 ID 不为空,则查询该子分类的子分类,并插入到临时表中。
  3. 如果子分类 ID 为空,则说明已经查询完所有子分类,退出循环。

最后通过 SELECT 查询临时表中的所有分类 ID,即为指定分类的所有子分类。

以上代码片段出自 MySQL 5.6 分层递归查询 - SQL