2017-04-03 78 views
1

我的当前表格对于1个用户来说是这样的。TSQL中的数据透视记录

NewCustomerID OldCustomerID RowID  Date 
111    NULL    1  2016-01-01 
222    111    321  2016-02-05 
333    222    5433  2017-03-01 
444    333    95312 2017-04-03 

下表是我最终结果所需要的。需要TSQL。

NewCustomerID OldCustomerID 
444    111    
444    222    
444    333 

我将使用上表更新所有OldCustomerID的最新NewCustomerID

+1

什么是由''NewCustomerID'成为444'每'OldCustomerID'相关的逻辑是什么? –

+1

@TimBiegeleisen我猜这些都是'444'在 – LONG

+0

之前使用的所有历史ID客户正在从一个位置迁移到另一个位置,所以他的customerID不断变化。每当customerID发生变化时,都会记录它是什么以及现在是什么。 – Etienne

回答

2

你正在寻找一个递归CTE:

with cte as (
     select t.NewCustomerID, t.OldCustomerID 
     from t 
     where not exists (select 1 from t t2 where t2.OldCustomerId = t.NewCustomerID) 
     union all 
     select cte.NewCustomerId, t.OldCustomerID 
     from cte join 
      t 
      on t.NewCustomerID = cte.OldCustomerID 
    ) 
select * 
from cte; 

Here是它的工作的例子。

+0

嗨戈登,'union all'的第一部分'1'是什么?似乎列数不匹配? – LONG

+0

以上对我不起作用,它不返回我的最终结果,因为在我的问题:( – Etienne

+0

@Etienne ...。它现在应该工作 –

1

试试这个

DECLARE @SampleDAta AS TABLE 
(
    NewCustomerID int, 
    OldCustomerID int 
) 
INSERT INTO @SampleDAta VALUES (111, NULL),(222,111),(333,222),(444,333),(1111, NULL),(2222,1111),(3333,2222),(4444,3333),(5555,4444) 

;with reTbl as (
     select t.NewCustomerID, t.OldCustomerID, 1 as lev, t.NewCustomerID AS RootId 
     from @SampleDAta t 
     where t.OldCustomerID IS NULL 
     union all 
     select t.NewCustomerId, t.OldCustomerID, reTbl.lev +1, reTbl.RootId 
     from reTbl join 
      @SampleDAta t 
      on t.OldCustomerID = reTbl.NewCustomerID 
    ), 
LastestId AS 
(
    SELECT c.RootId, max(c.lev) AS MaxLevel 
    FROM reTbl c 
    GROUP BY c.RootId 
) 

select reTbl.NewCustomerID, reTbl1.NewCustomerID AS OldCustomerID 
from reTbl 
INNER JOIN reTbl reTbl1 ON reTbl.RootId = reTbl1.RootId 
INNER JOIN LastestId t ON reTbl.RootId = t.RootId AND reTbl.lev = t.MaxLevel 
WHERE reTbl.NewCustomerID != reTbl1.NewCustomerID 
ORDER BY reTbl.NewCustomerID 
相关问题