本身我上面写的应该就可以了啊,弄个更通用的
with r as (
select b.BoxId,b.BallId,BoxIdFlag=cast(','+right(1000+b.BoxId,3) as varchar(200)),BallIdFlag=cast(','+right(1000+b.BallId,3) as varchar(200)),dep=1
from TC22_Preferences b
union all
select b.BoxId,b.BallId,BoxIdFlag=cast(BoxIdFlag+','+right(1000+b.BoxId,3) as varchar(200)),BallIdFlag=cast(BallIdFlag+','+right(1000+b.BallId,3) as varchar(200)),dep=a.dep+1
from
r a inner join
TC22_Preferences b on charindex(','+right(1000+b.BoxId,3),a.BoxIdFlag)=0 and charindex(','+right(1000+b.BallId,3),a.BallIdFlag)=0
)
,r1 as (
select top 1 BoxIdFlag,BallIdFlag from r where dep=(select count(*) from TC22_Boxes)
order by newid()
)
,rcount as (select _count=count(*) from TC22_Boxes)
,r2 as (
select BoxIdFlag,BallIdFlag,BoxId=substring(BoxIdFlag,2,3),BallId=substring(BallIdFlag,2,3),dep=0
from r1 a
union all
select BoxIdFlag,BallIdFlag,BoxId=substring(BoxIdFlag,b.number*4+2,3),BallId=substring(BallIdFlag,b.number*4+2,3),dep=b.number
from r2 a inner join
master.dbo.spt_values b on a.dep+1=b.number and b.type='P' and b.number<=(select _count from rcount)
)
select b.BoxName,c.BallName from r2 a inner join
TC22_Boxes b on a.BoxId=b.BoxId inner join
TC22_Balls c on a.BallId=c.BallId
order by 1
不使用临时表会付出更多的计算的代价,本身这个应该是从匹配最少的box开始,那样会最少的尝试代价