Oracle START WITH/CONNECT BY查询:仅取ID最新行及关联层级
解决Oracle层级查询中仅使用最新起始行的问题
我完全懂你的困扰:当存在多条ID为'X'的重复流程记录时,原查询会把所有这些行都当作层级追溯的起点,但你只需要基于最新的那一行往上关联父级流程。
核心思路
先通过子查询或CTE(公用表表达式)精准筛选出ID='X'的行里最新的那一条,再将它作为层级查询的唯一起始点,这样后续的CONNECT BY就只会基于这一行进行父级追溯。
方案1:子查询+ROWNUM快速筛选最新行
这是Oracle里取单条Top记录的经典写法,简洁高效:
SELECT ID, PARENT_ID, START_TIME FROM PROCESS START WITH ID = ( -- 先把ID='X'的行按时间倒序排序,取第一行的ID SELECT ID FROM ( SELECT ID FROM PROCESS WHERE ID = 'X' ORDER BY START_TIME DESC ) WHERE ROWNUM = 1 ) -- 按规则向上追溯父级流程 CONNECT BY ID = PRIOR PARENT_ID;
方案2:ROW_NUMBER()窗口函数(可读性更强)
如果后续需要扩展筛选逻辑,窗口函数的写法更清晰易懂:
WITH LatestProcessX AS ( SELECT ID, PARENT_ID, START_TIME, -- 给ID='X'的行按时间倒序编号,最新的行编号为1 ROW_NUMBER() OVER (ORDER BY START_TIME DESC) AS rn FROM PROCESS WHERE ID = 'X' ) SELECT p.ID, p.PARENT_ID, p.START_TIME FROM PROCESS p START WITH p.ID = (SELECT ID FROM LatestProcessX WHERE rn = 1) CONNECT BY p.ID = PRIOR p.PARENT_ID;
关键提示
- 这里默认用
START_TIME判断“最新”,如果你的业务里是用其他字段(比如更新时间),只需要把ORDER BY START_TIME DESC替换成对应的字段就行。 - 两种方案都是先锁定唯一的最新起始行,再执行层级查询,彻底解决了原语句多起始点的问题。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

