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

跨表递归查询开发:A、B表层级动作链查询需求

递归查询构建:动作链层级关系获取

一、数据表结构

TABLE A(仅作为动作链起始节点):

A_ID -- 主键,唯一标识A节点

TABLE B(可作为起始节点,或关联A/B节点):

B_ID          -- 主键,唯一标识B节点
LINKS_TO_A_ID -- 关联TABLE A的A_ID(可为空)
LINKS_TO_B_ID -- 关联TABLE B的B_ID(可为空)

注:B节点不能关联A节点(仅A可作为起始),链中出现A节点后只能向下关联B节点

二、层级规则说明

合法层级结构示例

A->B->B->B->B  -- 以A为起始,后续仅关联B节点
B->B->B        -- 以独立B为起始,后续仅关联B节点

非法层级结构示例

B->A->B  -- B节点不能关联A节点,更不能在A后继续延伸
B->A     -- B节点禁止关联A节点

三、需求说明

需构建递归查询实现:

  • 获取所有以A为起始的完整动作链(A→B→B...)
  • 获取所有以独立B为起始的完整动作链(B→B→B...)
  • 列出层级内所有关联节点
  • 兼容TABLE B同一行被多次引用的场景(如同一B节点被多个B节点关联)

四、示例关联数据

RowA1 -- TABLE A的起始节点
RowB1_referencingA1 -- TABLE B节点,关联RowA1
RowB2_referencingB1 -- TABLE B节点,关联RowB1
RowB3 -- TABLE B的独立起始节点(无关联)
RowB4_referencingB3 -- TABLE B节点,关联RowB3
RowB5_referencingB3 -- TABLE B节点,关联RowB3
RowB6_referencingB5 -- TABLE B节点,关联RowB5

五、递归查询实现(适配MySQL 8+/PostgreSQL)

1. 查询以A为起始的动作链

通过递归CTE从A节点出发,逐层关联合法B节点:

WITH RECURSIVE a_chain AS (
    -- 锚点:TABLE A所有起始节点
    SELECT 
        A_ID AS node_id,
        'A' AS node_type,
        CAST(A_ID AS CHAR) AS chain_path,
        1 AS level
    FROM TABLE_A

    UNION ALL

    -- 递归:关联A节点直接指向的B节点
    SELECT 
        b.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(ac.chain_path, '->', b.B_ID) AS chain_path,
        ac.level + 1 AS level
    FROM a_chain ac
    JOIN TABLE_B b ON ac.node_id = b.LINKS_TO_A_ID
    WHERE b.LINKS_TO_B_ID IS NULL

    UNION ALL

    -- 递归:关联B节点的下一级B节点
    SELECT 
        b_next.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(ac.chain_path, '->', b_next.B_ID) AS chain_path,
        ac.level + 1 AS level
    FROM a_chain ac
    JOIN TABLE_B b_next ON ac.node_id = b_next.LINKS_TO_B_ID
    WHERE ac.node_type = 'B'
      AND b_next.LINKS_TO_A_ID IS NULL
)
SELECT chain_path, level, node_id, node_type
FROM a_chain
ORDER BY chain_path, level;

2. 查询以独立B为起始的动作链

从无关联的B节点出发,逐层关联后续合法B节点:

WITH RECURSIVE b_chain AS (
    -- 锚点:TABLE B中无关联的独立起始节点
    SELECT 
        B_ID AS node_id,
        'B' AS node_type,
        CAST(B_ID AS CHAR) AS chain_path,
        1 AS level
    FROM TABLE_B
    WHERE LINKS_TO_A_ID IS NULL 
      AND LINKS_TO_B_ID IS NULL

    UNION ALL

    -- 递归:关联下一级B节点
    SELECT 
        b_next.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(bc.chain_path, '->', b_next.B_ID) AS chain_path,
        bc.level + 1 AS level
    FROM b_chain bc
    JOIN TABLE_B b_next ON bc.node_id = b_next.LINKS_TO_B_ID
    WHERE b_next.LINKS_TO_A_ID IS NULL
)
SELECT chain_path, level, node_id, node_type
FROM b_chain
ORDER BY chain_path, level;

3. 合并两类结果(可选)

若需一次性获取所有合法动作链,可合并两个CTE的结果:

WITH RECURSIVE a_chain AS (
    SELECT 
        A_ID AS node_id,
        'A' AS node_type,
        CAST(A_ID AS CHAR) AS chain_path,
        1 AS level
    FROM TABLE_A

    UNION ALL

    SELECT 
        b.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(ac.chain_path, '->', b.B_ID) AS chain_path,
        ac.level + 1 AS level
    FROM a_chain ac
    JOIN TABLE_B b ON ac.node_id = b.LINKS_TO_A_ID
    WHERE b.LINKS_TO_B_ID IS NULL

    UNION ALL

    SELECT 
        b_next.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(ac.chain_path, '->', b_next.B_ID) AS chain_path,
        ac.level + 1 AS level
    FROM a_chain ac
    JOIN TABLE_B b_next ON ac.node_id = b_next.LINKS_TO_B_ID
    WHERE ac.node_type = 'B'
      AND b_next.LINKS_TO_A_ID IS NULL
),
b_chain AS (
    SELECT 
        B_ID AS node_id,
        'B' AS node_type,
        CAST(B_ID AS CHAR) AS chain_path,
        1 AS level
    FROM TABLE_B
    WHERE LINKS_TO_A_ID IS NULL 
      AND LINKS_TO_B_ID IS NULL

    UNION ALL

    SELECT 
        b_next.B_ID AS node_id,
        'B' AS node_type,
        CONCAT(bc.chain_path, '->', b_next.B_ID) AS chain_path,
        bc.level + 1 AS level
    FROM b_chain bc
    JOIN TABLE_B b_next ON bc.node_id = b_next.LINKS_TO_B_ID
    WHERE b_next.LINKS_TO_A_ID IS NULL
)
SELECT chain_path, level, node_id, node_type FROM a_chain
UNION ALL
SELECT chain_path, level, node_id, node_type FROM b_chain
ORDER BY chain_path, level;

说明:上述查询通过递归CTE逐层遍历节点,通过WHERE条件过滤非法关联,确保生成的链均为合法结构。对于TABLE B中被多次引用的节点(如示例中的RowB3),递归会自动处理多分支,生成所有对应完整链。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:44:52