2017-04-18 189 views
0

我有一个包含2列OLD_VALUE和NEW_VALUE以及5行的表格。第一行有值(A,B)。其他行值可以是(B,C),(C,D),(E,D),(D,F)。我想用新值更新所有旧值(如何在Excel中进行查找)最终结果要求:以上示例中的最新值为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。在Excel中Vlookup函数的SQL逻辑/如何在SQL中执行Vlookup

+0

你怎么了知道哪一行是'第一',这是'最后'?你有一个表示订单的专栏吗? – cha

+0

不,不幸的是,没有表示订单的列。 –

+0

所以如果你在Excel中这样做,你会使用5个vlookups?问题不是很清楚...... –

回答

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; 
+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) 
+0

非常感谢!欣赏它! :) –

+0

我从中学到了一些东西,我一直认为它必须从A到F,但是你在另一个方向上构建它。我必须记住这一点。 –