Tsql递归连接

时间:2015-05-26 20:15:42

标签: sql-server-2008 tsql

DECLARE @Table TABLE(       
        URL VARCHAR(200),
        URLREDIRECT VARCHAR(200),
)

INSERT INTO @Table SELECT     'URL1','URL2'
INSERT INTO @Table SELECT     'URL2','URL3'
INSERT INTO @Table SELECT     'URL3','URL4'
INSERT INTO @Table SELECT     'URL5','URL6'
INSERT INTO @Table SELECT     'URL6','URL7'
INSERT INTO @Table SELECT     'URL7','URL8'

以上数据定义了URL是否被重定向,我希望能够确定URL被重定向的次数,因此URL 1将被重定向3次,因为URL1首先被重定向到URL2,而URL2又重定向到URL3,后者又重定向到URL4。

2 个答案:

答案 0 :(得分:2)

这可能比你想要的更多,但是这里是一个递归的CTE实现,包括检查URL是否循环回来,如果被困在一个循环中就挽救...

create table urls (       
    url VARCHAR(200),
    urlRedirect VARCHAR(200)
)

insert into urls select 'URL1','URL2'
insert into urls select 'URL2','URL3'
insert into urls select 'URL3','URL4'
insert into urls select 'URL5','URL6'
insert into urls select 'URL5','URL7'
insert into urls select 'URL6','URL8'
insert into urls select 'URL9','URL10'
insert into urls select 'URL10','URL11'
insert into urls select 'URL11','URL12'
insert into urls select 'URL12','URL9'

; with recursiveCTE as (
select 
    url as topURL, 
    url, 
    urlRedirect, 
    cast(url + '->' + urlRedirect as varchar(max)) as tree, 
    1 as depth,
    0 as infiniteLoop
from urls

union all

select 
    r.topUrl, 
    t.url, 
    t.urlRedirect, 
    cast(r.Tree + '->' + t.urlRedirect as varchar(max)), 
    r.depth + 1,
    case 
        when r.tree like '%' + t.url + '->' + t.urlRedirect + '%'
        then 1
        else 0
    end as infiniteLoop
from 
    recursiveCTE r 
    join urls t 
        on t.URL = r.urlRedirect
        and r.infiniteLoop = 0
),
deepest as (
select 
    *,
    row_number() over (partition by topUrl order by depth desc) as rn
from recursiveCTE
)
select
    topURL,
    tree,
    depth,
    infiniteLoop
from deepest
where rn = 1
order by topURL

SQL Fiddle Here

答案 1 :(得分:1)

SQL FIDDLE

从这里我认为你可以得到它。注意:由于URL5指向URL6和7等奇怪的原因,我改变了一些数据...不确定一个地址如何有两个目的地。

with cte as 
(Select url, urlredirect, 1 as lvl 
 from mtable where url='URL1'
 UNION ALL
 Select a.url, a.urlredirect, b.lvl+1
 from mtable a
 inner join cte b on a.url=b.urlredirect
 where a.url<>'URL1')

 Select * from cte

所以要查找最大重定向,请从lvl

中的Select * from cte获取最大值