我有一个包含2列OLD_VALUE和NEW_VALUE以及5行的表。第一行具有值(A,B)。其他行值可以是(B,C),(C,D),(E,D),(D,F)。我想用新值更新所有旧值(excel中的vlookup如何工作)最终结果要求:上例中的最新值为D,F。即D指向F. E指向C指向D. B指向C且A指向B.指向F的D是最后且最新的,并且在D,F之后没有更多的继承。所以(OLD_VALUE,NEW_VALUE) - >(A,F),(B,F),(C,F),(D,F),(E,F)。我想要5行,NEW_VALUE为'F'。继承级别可以从1到x。
答案 0 :(得分:1)
这是我用于脚本的表格:
declare @t as table(old_value char(1), new_value char(1));
insert into @t values('A','B')
insert into @t values('B','C')
insert into @t values('C','D')
insert into @t values('E','D')
insert into @t values('D','F')
这需要使用递归CTE完成。首先,您需要为CTE定义锚点。在这种情况下,锚点应该是具有最新值的记录。这是我定义锚点的方式:
select old_value, new_value, 1 as level
from @t
where new_value NOT IN (select old_value from @t)
这是我用来定位每行最新值的递归CTE:
;with a as(
select old_value, new_value, 1 as level
from @t
where new_value NOT IN (select old_value from @t)
union all
select b.old_value, a.new_value, a.level + 1
from a INNER JOIN @t b ON a.old_value = b.new_value
)
select * from a
结果:
old_value new_value level
--------- --------- -----------
D F 1
C F 2
E F 2
B F 3
A F 4
(5 row(s) affected)
答案 1 :(得分:0)
我认为像下面这样的递归CTE就是你正在寻找的东西(其中父级是第二个值不存在的行作为其他地方的第一个值)。如果没有父母要锚定,这将失败(例如,如果你有A-> B,B-> C,C-> A,你就没有结果) ,但它适用于您的情况:
DECLARE @T TABLE (val1 CHAR(1), val2 CHAR(2));
INSERT @T VALUES ('A', 'B'), ('B', 'C'), ('C', 'D'), ('E', 'D'), ('D', 'F');
WITH CTE AS
(
SELECT val1, val2
FROM @T AS T
WHERE NOT EXISTS (SELECT 1 FROM @T WHERE val1 = T.val2)
UNION ALL
SELECT T.val1, CTE.val2
FROM @T AS T
JOIN CTE
ON CTE.val1 = T.val2
)
SELECT *
FROM CTE;