递归查询理解
每一步理解
当使用 RECURSIVE 关键字执行递归查询时,每一步的结果都会被迭代地添加到结果集中,直到满足递归结束条件。
下面是一个使用 RECURSIVE 的示例,假设有一个名为 categories 的表,包含分类的 ID 和父分类的 ID:
CREATE TABLE categories (
id INT,
name VARCHAR(50),
parent_id INT
);
现在,我们想要获取一个分类及其所有的子分类(子分类的子分类等),我们可以使用 RECURSIVE 关键字来执行递归查询:
WITH RECURSIVE category_tree AS (
SELECT id, name, parent_id
FROM categories
WHERE id = 1 -- 假设要获取分类 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;
在上面的查询中,我们使用了一个公共表表达式(Common Table Expression,CTE),其中使用 RECURSIVE 关键字定义了一个名称为 category_tree 的递归查询。递归查询包含两个部分:
- 初始查询(Anchor Query):它是递归查询的起点。在上述示例中,初始查询选择了分类 ID 为 1 的记录。
- 递归查询(Recursive Query):它引用了 CTE 自身,并根据关联条件将子分类添加到结果集中。
在递归查询中,我们使用 UNION ALL 运算符将初始查询和递归查询的结果合并在一起。每次递归迭代时,子分类的记录会被添加到结果集中,并继续进行下一次迭代,直到没有更多的子分类满足条件。
下面是一个示例结果集的逐步生成过程:
初始查询:
id | name | parent_id
---+------------+----------
1 | Electronics| NULL
第一次递归查询:
id | name | parent_id
---+-----------------+----------
2 | Computers | 1
3 | Mobile Phones | 1
4 | Televisions | 1
第二次递归查询:
id | name | parent_id
---+-----------------+----------
5 | Laptops | 2
6 | Desktops | 2
7 | Smartphones | 3
8 | Feature Phones | 3
9 | LED | 4
10 | OLED | 4
以此类推,根据分类之间的父子关系,递归查询会继续迭代并返回所有满足条件的子分类,直到没有更多的子分类符合条件。
最后,主查询选择了 category_tree 表,它包含了递归查询的结果,即分类 ID 为 1 的分类及其所有子分类的记录。
UNION ALL 解析
试验了一下,列数一样就可以用 union all 结果合并。