SQL Server查询:获取ID变更链的初始值与最终值
查询ID变更链的初始值与最终值
原数据表
| changeOrder | oldValue | newValue |
|---|---|---|
| 0 | ID1 | ID2 |
| 1 | ID2 | ID3 |
| 2 | ID6 | ID7 |
| 3 | ID3 | ID4 |
| 4 | ID7 | ID8 |
需求
提取每条ID变更链的初始值(Oldest)和最终值(Newest),得到如下结果:
| Oldest | Newest |
|---|---|
| ID1 | ID4 |
| ID6 | ID8 |
解决方案(标准SQL)
可以通过**递归CTE(公共表表达式)**实现链式数据的追踪,以下是两种可行的写法:
写法一:通过分组取最终节点
WITH RECURSIVE change_chain AS ( -- 定位所有变更链的起点:从未作为newValue出现的oldValue SELECT oldValue AS oldest_id, oldValue AS current_id, newValue AS next_id FROM your_table WHERE oldValue NOT IN (SELECT newValue FROM your_table) UNION ALL -- 递归追踪后续节点 SELECT cc.oldest_id, t.newValue AS current_id, t.newValue AS next_id FROM change_chain cc JOIN your_table t ON cc.next_id = t.oldValue ) -- 按初始值分组,取组内最后一个节点作为最终值 SELECT oldest_id AS Oldest, MAX(current_id) AS Newest FROM change_chain GROUP BY oldest_id;
写法二:直接筛选链的末端节点
WITH RECURSIVE change_chain AS ( -- 定位所有变更链的起点 SELECT oldValue AS oldest_id, newValue AS current_id FROM your_table WHERE oldValue NOT IN (SELECT newValue FROM your_table) UNION ALL -- 递归追踪后续节点 SELECT cc.oldest_id, t.newValue AS current_id FROM change_chain cc JOIN your_table t ON cc.current_id = t.oldValue ) -- 筛选出不再作为变更起点的节点(即链的末端) SELECT oldest_id AS Oldest, current_id AS Newest FROM change_chain WHERE current_id NOT IN (SELECT oldValue FROM your_table);
逻辑说明
- 锚点查询:先找出所有变更链的初始节点——这些ID只出现在
oldValue中,从未作为newValue被其他ID指向。 - 递归查询:通过关联
current_id与oldValue,沿着变更关系逐层追踪,直到链的末端。 - 结果提取:要么通过分组取每条链的最后一个节点,要么直接筛选出不再作为变更起点的末端节点,最终得到初始值与最终值的对应关系。
内容的提问来源于stack exchange,提问作者MG_
相关产品推荐
相关产品推荐

