我有这张桌子
| old | new | |------|-------| | a | b | | b | c | | d | e | | ... | ... | | aa | bb | | bb | ff | | ... | ... | | 11 | 33 | | 33 | 523 | | 523 | 4444 | | 4444 | 21444 |
我想要达到的结果是
| old | newest | |------|--------| | a | e | | b | e | | d | e | | ... | | | aa | ff | | bb | ff | | ... | | | 11 | 21444 | | 33 | 21444 | | 523 | 21444 | | 4444 | 21444 |
我可以对查询进行硬编码以获得所需的结果。
SELECT older.old, older.new, newer.new firstcol, newer1.new secondcol, 鈥� newerX-1.new secondlastcol, newerX.new lastcol from Table older Left join Table newer on older.old = newer.new Left join Table newer1 on newer.new = newer1.old 鈥� Left join Table newerX-1 on newerX-2.new = newerX-1.old Left join Table newerX on newerX-1.new = newerX.old;
然后从右边获取不为null的第一个值。
图示在这里:
| old | new | firstcol | secondcol | thirdcol | fourthcol | | lastcol | |------|-------|----------|-----------|----------|-----------|-----|---------| | a | b | c | e | null | null | ... | null | | b | c | e | null | null | null | ... | null | | d | e | null | null | null | null | ... | null | | ... | ... | ... | ... | ... | ... | ... | null | | aa | bb | ff | null | null | null | ... | null | | bb | ff | null | null | null | null | ... | null | | ... | ... | ... | ... | ... | ... | ... | null | | 11 | 33 | 523 | 4444 | 21444 | null | ... | null | | 33 | 523 | 4444 | 21444 | null | null | ... | null | | 523 | 4444 | 21444 | null | null | null | ... | null | | 4444 | 21444 | null | null | null | null | ... | null |
问题是“替换链”的长度总是在变化(可以从10到100不等)。
必须有更好的方法来做到这一点?
您正在寻找的是一个递归查询。像这样的东西:
with cte (old, new, lev) as ( select old, new, 1 as lev from mytable union all select m.old, cte.new, cte.lev + 1 from mytable m join cte on cte.old = m.new ) select old, max(new) keep (dense_rank last order by lev) as new from cte group by old order by old;
递归CTE创建所有迭代(您可以通过将查询替换为来查看此迭代select * from cte)。而在最终的查询,我们得到最后的new每oldOracle的KEEP LAST。
select * from cte
new
old
KEEP LAST
Rextester演示:http ://rextester.com/CHTG34988