📜  PostgreSQL – 递归查询

📅  最后修改于: 2022-05-13 01:57:14.735000             🧑  作者: Mango

PostgreSQL – 递归查询

PostgreSQL 提供了 WITH 语句来支持辅助查询的设计,也称为 CTE(Common Table Expressions)。递归查询是引用递归 CTE 的查询。递归查询在许多情况下都很有用,例如查询组织结构、跟踪谱系等分层数据。

句法:

WITH RECURSIVE cte_name AS(
    CTE_query_definition Let's analyze the above syntax:
  • 非递归术语是一个 CTE 查询定义,它构成了 CTE 结构的基本结果集。
  • 递归项可以是通过 UNION 或 UNION ALL运算符与非递归项连接的一个或多个 CTE 查询定义。递归术语引用 CTE 名称本身。
  • 当前一次迭代没有返回任何行时,递归停止。

首先,我们使用以下命令创建一个示例表来执行示例:

CREATE TABLE employees (
    employee_id serial PRIMARY KEY,
    full_name VARCHAR NOT NULL,
    manager_id INT
);

然后我们将数据插入到我们的员工表中,如下所示:



INSERT INTO employees (
    employee_id,
    full_name,
    manager_id
)
VALUES
    (1, 'M.S Dhoni', NULL),
    (2, 'Sachin Tendulkar', 1),
    (3, 'R. Sharma', 1),
    (4, 'S. Raina', 1),
    (5, 'B. Kumar', 1),
    (6, 'Y. Singh', 2),
    (7, 'Virender Sehwag ', 2),
    (8, 'Ajinkya Rahane', 2),
    (9, 'Shikhar Dhawan', 2),
    (10, 'Mohammed Shami', 3),
    (11, 'Shreyas Iyer', 3),
    (12, 'Mayank Agarwal', 3),
    (13, 'K. L. Rahul', 3),
    (14, 'Hardik Pandya', 4),
    (15, 'Dinesh Karthik', 4),
    (16, 'Jasprit Bumrah', 7),
    (17, 'Kuldeep Yadav', 7),
    (18, 'Yuzvendra Chahal', 8),
    (19, 'Rishabh Pant', 8),
    (20, 'Sanju Samson', 8);

现在表格已准备就绪,我们可以查看一些示例。

示例 1:
下面的查询返回 id 为 3 的经理的所有下属。

WITH RECURSIVE subordinates AS (
    SELECT
        employee_id,
        manager_id,
        full_name
    FROM
        employees
    WHERE
        employee_id = 3
    UNION
        SELECT
            e.employee_id,
            e.manager_id,
            e.full_name
        FROM
            employees e
        INNER JOIN subordinates s ON s.employee_id = e.manager_id
) SELECT
    *
FROM
    subordinates;

输出:

示例 2:
下面的查询返回 id 为 4 的经理的所有下属。

WITH RECURSIVE subordinates AS (
    SELECT
        employee_id,
        manager_id,
        full_name
    FROM
        employees
    WHERE
        employee_id = 4
    UNION
        SELECT
            e.employee_id,
            e.manager_id,
            e.full_name
        FROM
            employees e
        INNER JOIN subordinates s ON s.employee_id = e.manager_id
) SELECT
    *
FROM
    subordinates;

输出: