MySQL基础操作指南:为数据管理打下坚实基础

在MySQL中,CONNECT BY START WITH 是 Oracle 数据库中用于实现层次查询(Hierarchical Query)的语法,而 MySQL 并不直接支持这种语法。不过,我们可以使用递归公用表表达式(Common Table Expressions, CTEs)来实现类似的功能。

图片[1]_MySQL基础操作指南:为数据管理打下坚实基础_知途无界

从 MySQL 8.0 开始,引入了递归 CTE,这使得我们可以模拟层次查询。下面是一个示例,展示了如何使用递归 CTE 来实现 Oracle 中 CONNECT BY START WITH 的功能。

假设我们有一个员工表 employees,结构如下:

CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
manager_id INT
);
CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    manager_id INT
);
CREATE TABLE employees ( id INT PRIMARY KEY, name VARCHAR(100), manager_id INT );

并且表中有以下数据:

INSERT INTO employees (id, name, manager_id) VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Charlie', 1),
(4, 'David', 2),
(5, 'Eve', 2),
(6, 'Frank', 3);
INSERT INTO employees (id, name, manager_id) VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Charlie', 1),
(4, 'David', 2),
(5, 'Eve', 2),
(6, 'Frank', 3);
INSERT INTO employees (id, name, manager_id) VALUES (1, 'Alice', NULL), (2, 'Bob', 1), (3, 'Charlie', 1), (4, 'David', 2), (5, 'Eve', 2), (6, 'Frank', 3);

在这个表中,id 是员工的唯一标识,name 是员工的名字,manager_id 是员工的经理的 id。我们希望查询出所有员工及其上级经理的层次结构。

可以使用递归 CTE 来实现这个查询:

WITH RECURSIVE employee_hierarchy AS (
-- 基础查询,相当于 START WITH
SELECT
id,
name,
manager_id,
CAST(name AS CHAR(255)) AS path,
1 AS level
FROM
employees
WHERE
manager_id IS NULL
UNION ALL
-- 递归部分,相当于 CONNECT BY
SELECT
e.id,
e.name,
e.manager_id,
CONCAT(eh.path, ' -> ', e.name) AS path,
eh.level + 1 AS level
FROM
employees e
INNER JOIN
employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT
id,
name,
manager_id,
path,
level
FROM
employee_hierarchy
ORDER BY
path;
WITH RECURSIVE employee_hierarchy AS (
    -- 基础查询,相当于 START WITH
    SELECT 
        id, 
        name, 
        manager_id,
        CAST(name AS CHAR(255)) AS path,
        1 AS level
    FROM 
        employees
    WHERE 
        manager_id IS NULL

    UNION ALL

    -- 递归部分,相当于 CONNECT BY
    SELECT 
        e.id, 
        e.name, 
        e.manager_id,
        CONCAT(eh.path, ' -> ', e.name) AS path,
        eh.level + 1 AS level
    FROM 
        employees e
    INNER JOIN 
        employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT 
    id, 
    name, 
    manager_id,
    path,
    level
FROM 
    employee_hierarchy
ORDER BY 
    path;
WITH RECURSIVE employee_hierarchy AS ( -- 基础查询,相当于 START WITH SELECT id, name, manager_id, CAST(name AS CHAR(255)) AS path, 1 AS level FROM employees WHERE manager_id IS NULL UNION ALL -- 递归部分,相当于 CONNECT BY SELECT e.id, e.name, e.manager_id, CONCAT(eh.path, ' -> ', e.name) AS path, eh.level + 1 AS level FROM employees e INNER JOIN employee_hierarchy eh ON e.manager_id = eh.id ) SELECT id, name, manager_id, path, level FROM employee_hierarchy ORDER BY path;

在这个查询中:

  1. WITH RECURSIVE employee_hierarchy AS (...) 定义了递归 CTE。
  2. 第一个 SELECT 语句(基础查询)选择顶层员工(即没有经理的员工),这相当于 Oracle 中的 START WITH 部分。
  3. UNION ALL 将基础查询的结果与递归部分的结果合并。
  4. 递归部分选择每个员工的上级经理,并将路径和层级信息添加到结果集中。
  5. 最终的 SELECT 语句从递归 CTE 中选择所需的数据,并按路径排序以显示层次结构。

运行这个查询,你会得到类似如下的结果:

+----+---------+------------+-----------------------+-------+
| id | name | manager_id | path | level |
+----+---------+------------+-----------------------+-------+
| 1 | Alice | NULL | Alice | 1 |
| 2 | Bob | 1 | Alice -> Bob | 2 |
| 3 | Charlie | 1 | Alice -> Charlie | 2 |
| 4 | David | 2 | Alice -> Bob -> David | 3 |
| 5 | Eve | 2 | Alice -> Bob -> Eve | 3 |
| 6 | Frank | 3 | Alice -> Charlie -> Frank | 3 |
+----+---------+------------+-----------------------+-------+
+----+---------+------------+-----------------------+-------+
| id | name    | manager_id | path                  | level |
+----+---------+------------+-----------------------+-------+
|  1 | Alice   |       NULL | Alice                 |     1 |
|  2 | Bob     |          1 | Alice -> Bob          |     2 |
|  3 | Charlie |          1 | Alice -> Charlie      |     2 |
|  4 | David   |          2 | Alice -> Bob -> David |     3 |
|  5 | Eve     |          2 | Alice -> Bob -> Eve   |     3 |
|  6 | Frank   |          3 | Alice -> Charlie -> Frank |     3 |
+----+---------+------------+-----------------------+-------+
+----+---------+------------+-----------------------+-------+ | id | name | manager_id | path | level | +----+---------+------------+-----------------------+-------+ | 1 | Alice | NULL | Alice | 1 | | 2 | Bob | 1 | Alice -> Bob | 2 | | 3 | Charlie | 1 | Alice -> Charlie | 2 | | 4 | David | 2 | Alice -> Bob -> David | 3 | | 5 | Eve | 2 | Alice -> Bob -> Eve | 3 | | 6 | Frank | 3 | Alice -> Charlie -> Frank | 3 | +----+---------+------------+-----------------------+-------+

这样,我们就用递归 CTE 在 MySQL 中实现了类似于 Oracle CONNECT BY START WITH 的层次查询功能。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞66 分享
Don't give up just because of what people said. Use that as your motivation to push harder.
别因为别人说的话而放弃,把那些话当做加倍努力的动力
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容