Reputation: 33
I have a query setup below, and I'm having trouble with the recursion piece. I start with a contract(s), Abc and Xyz from Table1. I take Table1.Id, groupNo and look them up in Table2, to get the contracts(s) there, then look those contracts back up in Table1, repeating the process until it eventually returns null, and capturing the last iteration. Is CTE the way to handle this? If so, could someone help with the last iteration. I tried nesting, and haven't got it to work.
create table Table1 (id int, groupNo int, contract varchar(3))
insert into Table1 values(33,2,'Abc')
insert into Table1 values(34,8,'Xyz')
insert into Table1 values(88,11,'123')
insert into Table1 values(89,11,'456')
create table Table2 (id int, groupNo int, contract varchar(3))
insert into Table2 values(34,8,'123')
insert into Table2 values(34,8,'456')
insert into Table2 values(89,11,'789')
with myCTE (id,groupNo,contract) as
(
select
t1.id
,t1.groupNo
,t2.contract
from Table1 t1
inner join Table2 t2 on t1.id = t2.id and t1.groupNo = t2.groupNo
union all
select
t1.id
,t1.groupNo
,c2.contract
from myCTE c2
inner join Table1 t1 on c2.contract = t1.contract
)
select top 10 id, groupNo, contract
from myCTE
SQL FIDDLE
Upvotes: 2
Views: 46
Reputation: 3952
This is one way of doing it. Basically, I record the level of each recursion and only keep the highest level. See SQL Fiddle and query below:
declare @Table1 table(id int, groupNo int, contract varchar(3));
insert into @Table1 values(33,2,'Abc');
insert into @Table1 values(34,8,'Xyz');
insert into @Table1 values(88,11,'123');
insert into @Table1 values(89,11,'456');
declare @Table2 table(id int, groupNo int, contract varchar(3));
insert into @Table2 values(34,8,'123');
insert into @Table2 values(34,8,'456');
insert into @Table2 values(89,11,'789');
with myCTE (level, id, groupNo, contract, subcontract) as
(
select 0, t1.id,t1.groupNo, t1.contract
,t2.contract
from @Table1 t1
inner join @Table2 t2 on t1.id = t2.id and t1.groupNo = t2.groupNo
union all
select level+1, c2.id, c2.groupNo, c2.contract
,t2.contract
from myCTE c2
inner join @Table1 t1 on c2.subcontract = t1.contract
inner join @Table2 t2 on t1.id = t2.id and t1.groupNo = t2.groupNo
)
Select c.* From myCTE as c
Inner join (select id, groupNo, contract, level = max(level) From myCTE Group by id, groupNo, contract) as m
On m.level = c.level and m.id = c.id and m.groupNo = c.groupNo and m.contract = c.contract
OPTION (MAXRECURSION 0);
I also added table2 to the second select. You want it to behave like the first one and it needs to get the subcontract name from table2.
Upvotes: 1