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

Oracle SQL:如何查询同一张表中的最终名称值?

如何用SQL追踪名称变更链路并获取最终名称与状态?

这个问题本质是处理层级链式的数据关系,正好可以用SQL里的递归CTE(Common Table Expression)来解决,我给你一步步拆解:

首先先明确你的数据场景和需求:

原始数据表

+---------+-------------+-----------+
| Name    | Name_Change | Status    |
+---------+-------------+-----------+
| Rick    | Brandon     | Cancelled |
| Brenda  | Alexa       | Active    |
| Brandon | TJ          | Cancelled |
| TJ      | Jonathan    | Active    |
| Randy   |             | Active    |
+---------+-------------+-----------+

需求目标

追踪Rick的完整名称变更链路 Rick --> Brandon --> TJ --> Jonathan,最终输出起始名称、最终名称和对应的最终状态,期望结果:

+------+------------+--------+
| Name | Final Name | Status |
+------+------------+--------+
| Rick | Jonathan   | Active |
+------+------------+--------+

解决方案:使用递归CTE

递归CTE是处理这类层级关联数据的标准方法,它分为锚点成员(定义起始行)和递归成员(循环遍历关联行)两部分:

WITH RECURSIVE name_change_chain AS (
    -- 锚点成员:定位到Rick的初始记录
    SELECT 
        Name AS original_name,
        Name_Change AS current_next_name,
        Status,
        1 AS chain_level
    FROM your_table_name
    WHERE Name = 'Rick'
    
    UNION ALL
    
    -- 递归成员:循环遍历每一层的名称变更
    SELECT 
        ncc.original_name,
        t.Name_Change AS current_next_name,
        t.Status,
        ncc.chain_level + 1 AS chain_level
    FROM name_change_chain ncc
    JOIN your_table_name t ON ncc.current_next_name = t.Name
    -- 终止条件:当没有下一个名称变更时停止
    WHERE t.Name_Change IS NOT NULL
)
-- 从递归结果中提取最终节点的信息
SELECT 
    original_name AS Name,
    -- 处理最终节点没有后续变更的情况,用节点自身名称作为最终名称
    COALESCE(
        current_next_name,
        (SELECT Name FROM your_table_name WHERE Name = (SELECT MAX(current_next_name) FROM name_change_chain))
    ) AS Final_Name,
    Status
FROM name_change_chain
WHERE chain_level = (SELECT MAX(chain_level) FROM name_change_chain);

代码细节解释

  1. 锚点成员:先抓取Rick的第一条记录,保存他的原始名称、下一个变更名称、当前状态和链路层级标记。
  2. 递归成员:每次用当前记录的current_next_name去关联表中的Name字段,找到下一个变更的记录,同时层级数加1,直到遇到Name_Change为空的节点(没有后续变更)。
  3. 最终查询:筛选出递归结果中层级最高的记录(也就是链路的终点),用COALESCE处理终点没有后续变更的情况,确保能正确获取最终名称。

简化版(适配你的示例场景)

如果你的数据链路是完整无中断的,也可以用更简洁的写法:

WITH RECURSIVE name_chain AS (
    SELECT Name, Name_Change, Status
    FROM your_table_name
    WHERE Name = 'Rick'
    UNION ALL
    SELECT nc.Name, t.Name_Change, t.Status
    FROM name_chain nc
    JOIN your_table_name t ON nc.Name_Change = t.Name
)
SELECT 
    'Rick' AS Name,
    -- 取链路中最后一个有效的名称(要么是最后一个Name_Change,要么是终点的Name)
    CASE WHEN MAX(Name_Change) IS NOT NULL THEN MAX(Name_Change) ELSE MAX(Name) END AS Final_Name,
    MAX(Status) AS Status
FROM name_chain;

这个版本利用了你的示例链路特性,直接取递归结果中的最大有效名称和对应状态,代码更简洁。

内容的提问来源于stack exchange,提问作者m.barros

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:02:45