代码:
CREATE TABLE #Temp ( ID INT, BranchID_New INT, BranchID_Old INT, DateCreated DATETIME2, PRIMARY KEY ( [ID], [BranchID_New], [BranchID_Old] ) ) ;
INSERT INTO #Temp
SELECT 1, 1, 1, '2018-04-11 00:00:00.0000000'
UNION ALL
SELECT 1, 2, 2, '2018-04-11 00:00:00.0000000'
UNION ALL
SELECT 1, 3, 3, '2018-04-11 00:00:00.0000000'
UNION ALL
SELECT 1, 4, 1, '2018-04-11 12:00:00.0000000' -- BranchID_New 1 and 2 were combined to BranchID_New 4
UNION ALL
SELECT 1, 4, 2, '2018-04-11 12:00:00.0000000' -- BranchID_New 1 and 2 were combined to BranchID_New 4
UNION ALL
SELECT 1, 4, 4, '2018-04-11 12:00:00.0000000' -- Also, BranchID_New 4 has its own record as well
UNION ALL
SELECT 1, 5, 5, '2018-04-11 14:00:00.0000000'
UNION ALL
SELECT 1, 6, 3, '2018-04-11 16:00:00.0000000' -- BranchID_New 3 and 4 (newly combined) were combined to BranchID_New 6
UNION ALL
SELECT 1, 6, 4, '2018-04-11 16:00:00.0000000' -- BranchID_New 3 and 4 (newly combined) were combined to BranchID_New 6
UNION ALL
SELECT 1, 6, 6, '2018-04-11 16:00:00.0000000' -- Also, BranchID_New 6 has its own record as well
UNION ALL
SELECT 2, 7, 7, '2018-04-12 00:00:00.0000000'
UNION ALL
SELECT 2, 8, 8, '2018-04-11 00:00:00.0000000'
UNION ALL
SELECT 2, 9, 9, '2018-04-11 00:00:00.0000000'
UNION ALL
SELECT 2, 10, 8, '2018-04-11 12:00:00.0000000' -- BranchID_New 8 and 9 were combined to BranchID_New 10
UNION ALL
SELECT 2, 10, 9, '2018-04-11 12:00:00.0000000' -- BranchID_New 8 and 9 were combined to BranchID_New 10
UNION ALL
SELECT 2, 10, 10, '2018-04-11 12:00:00.0000000' -- Also, BranchID_New 10 has its own record as well
UNION ALL
SELECT 3, 11, 11, '2018-04-12 00:00:00.0000000'
UNION ALL
SELECT 3, 12, 12, '2018-04-12 00:00:00.0000000'
UNION ALL
SELECT 3, 13, 13, '2018-04-12 00:00:00.0000000'
SELECT *
FROM #Temp ;
DROP TABLE #Temp ;
目标: BranchID_Old组合成BranchID_New。然后他们可以进一步组合成更新的BranchID_New。对于每个BranchID_Old,我想找到最新的BranchID_New。另外,我想找到每个BranchID_Old的分层路径。
期望的输出:
ID BranchID_New BranchID_Old DateCreated New_BranchID_New New_BranchID_New_Path
1 1 1 2018-04-11 00:00:00.000 6 1/4/6/
1 2 2 2018-04-11 00:00:00.000 6 2/4/6/
1 3 3 2018-04-11 00:00:00.000 6 3/6/
1 4 1 2018-04-11 12:00:00.000 6 4/6/
1 4 2 2018-04-11 12:00:00.000 6 4/6/
1 4 4 2018-04-11 12:00:00.000 6 4/6/
1 5 5 2018-04-11 14:00:00.000 5 5/
1 6 3 2018-04-11 16:00:00.000 6 6/
1 6 4 2018-04-11 16:00:00.000 6 6/
1 6 6 2018-04-11 16:00:00.000 6 6/
2 7 7 2018-04-12 00:00:00.000 7 7/
2 8 8 2018-04-11 00:00:00.000 10 8/10/
2 9 9 2018-04-11 00:00:00.000 10 9/10/
2 10 8 2018-04-11 12:00:00.000 10 10/
2 10 9 2018-04-11 12:00:00.000 10 10/
2 10 10 2018-04-11 12:00:00.000 10 10/
3 11 11 2018-04-12 00:00:00.000 11 11/
3 12 12 2018-04-12 00:00:00.000 12 12/
3 13 13 2018-04-12 00:00:00.000 13 13/
答案 0 :(得分:1)
对于层次结构,您可以使用递归cte。根据您的方案,您将排除层次结构的中间部分,如路径1/4。
见下面的代码。
;With cte AS
(--we start with all records
select [ID], [BranchID_New], [BranchID_Old],DateCreated,[BranchID_New] as [New_BranchID_New],cast('' as varchar(max)) as BranchPath
from #Temp
UNION ALL
select c.[ID],c.[BranchID_New], c.BranchID_Old,c.DateCreated,t.BranchID_New as New_BranchID_New
,c.BranchPath+cast(c.New_BranchID_New as varchar(max))+'/'--we add the child's newest to the path, which means we will need to add then most new later.
from #Temp t
join cte c on c.New_BranchID_New=t.BranchID_Old and c.ID=t.ID
WHERE c.New_BranchID_New<>t.BranchID_New --we avoid recusion over parents with the same parent
)
select [ID], [BranchID_New], [BranchID_Old],New_BranchID_New, DateCreated,BranchPath
into #NewBranches
from cte
--we need to remove all the lower hierarchy records, so we will delete them from the results
delete nb1
from #NewBranches nb1
join #NewBranches nb2 on nb1.ID=nb2.ID and nb1.BranchID_New=nb2.BranchID_New and nb1.BranchID_Old=nb2.BranchID_Old and nb1.DateCreated=nb2.DateCreated
where nb1.BranchPath<nb2.BranchPath
--we create the path based on hierarchy and add the BranchID_Newest
select ID, BranchID_New,BranchID_Old,DateCreated,New_BranchID_New as New_BranchID_New
,case when BranchID_New=New_BranchID_New then ''--current record is the newest
when BranchID_New<>New_BranchID_New then ''+BranchPath--keep path
end +cast(New_BranchID_New as varchar(max))+'/'
as New_BranchID_New_Path
from #NewBranches
order by 1,2,3
答案 1 :(得分:1)
你需要递归。这是一个选项
with rcte as (
select
*, New_BranchID_New = BranchID_New, step = 1, DateCreated_New = DateCreated
, New_BranchID_New_Path = cast(concat(BranchID_New, '/') as varchar(2000))
from
#Temp
union all
select
a.ID, a.BranchID_New, a.BranchID_Old, a.DateCreated, b.BranchID_New, step + 1
, b.DateCreated, cast(concat(a.New_BranchID_New_Path, b.BranchID_New, '/') as varchar(2000))
from
rcte a
join #Temp b on a.New_BranchID_New = b.BranchID_Old
and b.BranchID_New <> b.BranchID_Old
and a.DateCreated_New < b.DateCreated
)
select
ID, BranchID_New, BranchID_Old, DateCreated, New_BranchID_New, New_BranchID_New_Path
from (
select
ID, BranchID_New, BranchID_Old, DateCreated, New_BranchID_New, New_BranchID_New_Path
, rn = row_number() over (partition by ID, BranchID_New, BranchID_Old, DateCreated order by step desc)
from
rcte
) t
where
rn = 1
输出
ID BranchID_New BranchID_Old DateCreated New_BranchID_New New_BranchID_New_Path
--------------------------------------------------------------------------------------------------
1 1 1 2018-04-11 00:00:00.0000000 6 1/4/6/
1 2 2 2018-04-11 00:00:00.0000000 6 2/4/6/
1 3 3 2018-04-11 00:00:00.0000000 6 3/6/
1 4 1 2018-04-11 12:00:00.0000000 6 4/6/
1 4 2 2018-04-11 12:00:00.0000000 6 4/6/
1 4 4 2018-04-11 12:00:00.0000000 6 4/6/
1 5 5 2018-04-11 14:00:00.0000000 5 5/
1 6 3 2018-04-11 16:00:00.0000000 6 6/
1 6 4 2018-04-11 16:00:00.0000000 6 6/
1 6 6 2018-04-11 16:00:00.0000000 6 6/
2 7 7 2018-04-12 00:00:00.0000000 7 7/
2 8 8 2018-04-11 00:00:00.0000000 10 8/10/
2 9 9 2018-04-11 00:00:00.0000000 10 9/10/
2 10 8 2018-04-11 12:00:00.0000000 10 10/
2 10 9 2018-04-11 12:00:00.0000000 10 10/
2 10 10 2018-04-11 12:00:00.0000000 10 10/
3 11 11 2018-04-12 00:00:00.0000000 11 11/
3 12 12 2018-04-12 00:00:00.0000000 12 12/
3 13 13 2018-04-12 00:00:00.0000000 13 13/