返回

递归 CTE 揭秘:从 MySQL 单查询获取相关数据

mysql

从 MySQL 中使用单个查询检索相关数据:揭开递归 CTE 的秘密

简介

在管理层次结构数据时,比如树状结构或分类目录,经常需要查询与特定实体相关的所有其他实体。MySQL 中的递归 CTE(公共表表达式)是一种强大的工具,可以轻松地实现这一目标。本文将深入探讨递归 CTE,并展示如何使用它从数据库中选择与其他行中相关用户 ID 关联的数据。

递归 CTE 的魔力

递归 CTE 允许我们通过多次应用相同的查询来递归地遍历表。这使其非常适合处理层次结构数据,因为我们可以逐步向下钻取树状结构,直到达到所需深度。

问题陈述

假设我们有一个 categories 表,其中存储着分类目录数据。每个类别都可以有一个父类别,因此形成一个层次结构。我们的目标是编写一个查询,从表中选择与给定父类别 ID 关联的所有子类别的 ID。

解决方案

WITH RECURSIVE ChildCategories AS (
    SELECT
        id,
        parent_id
    FROM
        categories
    WHERE
        parent_id = ?  -- 替换为给定的父 ID,例如 19
    UNION ALL
    SELECT
        categories.id,
        categories.parent_id
    FROM
        categories
    INNER JOIN
        ChildCategories ON categories.parent_id = ChildCategories.id
)
SELECT
    id
FROM
    ChildCategories
WHERE
    parent_id IS NOT NULL;

查询分解

  • 递归 CTE(ChildCategories): 创建递归 CTE,其包含 id 和 parent_id 列。初始查询选择给定父 ID 的类别,UNION ALL 分支递归地检索子类别的父类别 ID。
  • 最终查询: 选择具有非空 parent_id 的 id,这表示子类别。

示例

考虑 categories 表:

id parent_id
19 NULL
20 19
21 20
22 21

对于父 ID 19,查询将返回以下结果:

id
20
21
22

注意:

  • 确保 categories 表中没有环形引用,否则查询将无限递归。
  • 如果你需要子类别的完整路径,可以使用类似的查询并添加一个额外的列来存储路径。

结论

通过使用递归 CTE,我们可以轻松地从层次结构数据中检索相关数据。这种方法避免了使用复杂子查询或循环,并提供了高效且简洁的解决方案。

常见问题解答

  1. 什么是递归 CTE? 递归 CTE 允许我们通过多次应用相同的查询来递归地遍历表。
  2. 递归 CTE 如何用于检索相关数据? 通过创建递归 CTE 并使用初始条件,我们可以逐步向下钻取层次结构并检索与给定实体相关的所有其他实体。
  3. 如何在 MySQL 中使用递归 CTE? 使用 WITH RECURSIVE 语法创建递归 CTE,并指定初始查询和递归步骤。
  4. 递归 CTE 的限制是什么? 递归 CTE 必须以明确的终止条件结束,否则查询将无限递归。
  5. 什么时候应该使用递归 CTE? 递归 CTE 非常适合处理层次结构数据,例如树状结构或分类目录,需要检索相关实体。