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

如何用Postgres递归查询和窗口函数生成订单表层级树形结构

以下实现基于PostgreSQL语法,若使用其他SQL方言可对应调整语法细节:

实现步骤

步骤1:新增parent字段

ALTER TABLE ORDERS ADD COLUMN parent INT NULL;

步骤2:创建指定序列

CREATE SEQUENCE seq_orders START WITH 1 INCREMENT BY 1;

步骤3:插入层级节点并关联parent

3.1 插入一级分类节点(顶级节点parent为null)

INSERT INTO ORDERS (id, description, parent)
SELECT nextval('seq_orders'), category, NULL
FROM (SELECT DISTINCT category FROM ORDERS) distinct_cats;

3.2 插入二级子分类节点,parent关联对应一级分类ID

WITH cat_level AS (
    -- 拿到所有一级分类的ID和名称
    SELECT id AS cat_id, description AS cat_name
    FROM ORDERS
    WHERE parent IS NULL
)
INSERT INTO ORDERS (id, description, parent)
SELECT nextval('seq_orders'), subcategory, cat_id
FROM (
    SELECT DISTINCT o.category, o.subcategory, c.cat_id
    FROM ORDERS o
    JOIN cat_level c ON o.category = c.cat_name
    WHERE o.id >= 1000 -- 过滤刚插入的一级节点,仅用原始业务数据去重子分类
) distinct_subcats;

3.3 更新原始业务行(三级描述节点)的parent关联对应二级子分类ID

WITH subcat_level AS (
    -- 拿到所有二级子分类的ID、名称、所属一级分类名称
    SELECT s.id AS subcat_id, s.description AS subcat_name, p.description AS cat_name
    FROM ORDERS s
    JOIN ORDERS p ON s.parent = p.id
    WHERE p.parent IS NULL
)
UPDATE ORDERS o
SET parent = sl.subcat_id
FROM subcat_level sl
WHERE o.category = sl.cat_name 
  AND o.subcategory = sl.subcat_name
  AND o.id >= 1000; -- 仅更新原始业务数据行

步骤4:删除冗余字段

ALTER TABLE ORDERS DROP COLUMN category, DROP COLUMN subcategory;

递归查询生成树形展示结果

使用窗口函数控制排序、递归CTE生成层级缩进:

WITH RECURSIVE order_tree AS (
    -- 锚点:查询顶级分类节点
    SELECT
        id,
        description,
        parent,
        0 AS level,
        -- 构造排序路径,保证树形顺序正确
        ARRAY[ROW_NUMBER() OVER(ORDER BY description)] AS sort_path
    FROM ORDERS
    WHERE parent IS NULL

    UNION ALL

    -- 递归:查询子节点
    SELECT
        o.id,
        o.description,
        o.parent,
        ot.level + 1 AS level,
        ot.sort_path || ROW_NUMBER() OVER(PARTITION BY o.parent ORDER BY o.description)
    FROM ORDERS o
    JOIN order_tree ot ON o.parent = ot.id
)
-- 按层级拼接缩进符号输出结果
SELECT
    CASE level
        WHEN 0 THEN description
        WHEN 1 THEN '  -> ' || description
        WHEN 2 THEN '    -> ' || description
    END AS result
FROM order_tree
ORDER BY sort_path;

执行后输出结果完全匹配需求的树形结构。


内容的提问来源于stack exchange,提问作者Carlos Davila

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 01:24:04