excel中Vlookup函数的SQL逻辑/如何在SQL中执行Vlookup

时间:2017-04-18 04:58:23

标签: sql sql-server

我有一个包含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。

2 个答案:

答案 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;