You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQL生成单列完整父子ID列表的技术实现问询

解决递归遍历父子关系并输出单列ID的方案

我完全懂你的困扰——找了一堆示例全是两列展示父子层级,但你只需要把所有关联的ID整合到单独一列里。针对你的Documents表(包含Id、ParentId字段,ParentId可为空),下面分不同数据库给出精准实现方案:

适用于SQL Server、MySQL 8.0+、PostgreSQL的CTE递归写法

递归公共表表达式(CTE)是处理这种层级关系的常用方式,我们可以通过它遍历所有父子节点,最终只输出Id列:

WITH RecursiveDocuments AS (
    -- 锚点成员:先取出所有顶级节点(ParentId为NULL的记录)
    SELECT Id
    FROM Documents
    WHERE ParentId IS NULL

    UNION ALL

    -- 递归成员:关联子节点,直到没有更多层级
    SELECT d.Id
    FROM Documents d
    INNER JOIN RecursiveDocuments rd ON d.ParentId = rd.Id
)
-- 最终只查询单列的Id
SELECT Id FROM RecursiveDocuments;

如果需要针对某个特定父节点的所有子节点(而非所有顶级节点),只需修改锚点成员的条件,比如查询Id=123节点的所有后代:

WITH RecursiveDocuments AS (
    SELECT Id
    FROM Documents
    WHERE Id = 123 -- 指定起始节点

    UNION ALL

    SELECT d.Id
    FROM Documents d
    INNER JOIN RecursiveDocuments rd ON d.ParentId = rd.Id
)
SELECT Id FROM RecursiveDocuments;

适用于Oracle的CONNECT BY写法

Oracle用CONNECT BY语法处理层级查询,同样可以只输出单列ID:

-- 查询所有顶级节点及其所有后代
SELECT Id
FROM Documents
START WITH ParentId IS NULL
CONNECT BY PRIOR Id = ParentId;

-- 查询特定节点的所有后代
SELECT Id
FROM Documents
START WITH Id = 123
CONNECT BY PRIOR Id = ParentId;

额外优化(可选)

如果需要按层级顺序输出ID,可以在查询里加入层级字段并排序,以SQL Server为例:

WITH RecursiveDocuments AS (
    SELECT Id, 1 AS Level
    FROM Documents
    WHERE ParentId IS NULL

    UNION ALL

    SELECT d.Id, rd.Level + 1 AS Level
    FROM Documents d
    INNER JOIN RecursiveDocuments rd ON d.ParentId = rd.Id
)
SELECT Id FROM RecursiveDocuments ORDER BY Level, Id;

内容的提问来源于stack exchange,提问作者Prisoner ZERO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:27:45