Это ссылка, которую я использовал, чтобы найти решение ..
http://wiki.lessthandot.com/index.php/Using_Common_Table_Expressions_for_Parent-Child_Relationships
РЕДАКТИРОВАТЬ - @Pshimo - спасибо. Вот руководство по ссылке.
С SQL 2005, хотя это мечта. Скажем, у вас есть этот пример данных:
declare @test table (bunchof uniqueidentifier default newid(), columns uniqueidentifier default newid(), Id int, ParentID int)
insert @test (Id, ParentId)
select 1, null
union all select 5, 1
union all select 15, 2
union all select 16, 5
union all select 27, 16
И вы хотите получить все дочерние строки для 1 (так ItemId 5, 16, 27)
declare @parentId int
set @parentId = 1
;--last statement MUST be semicolon-terminated to use a CTE
with CTE (bunchof, columns, Id, ParentId) as
(
select bunchof, columns, Id, ParentId
from @test
where ParentId = @parentId
union all
select a.bunchof, a.columns, a.Id, a.ParentId
from @test as a
inner join CTE as b on a.ParentId = b.Id
)
select * from CTE
и если вы хотите включить родителя:
declare @Id int
set @Id = 1
;--last statement MUST be semicolon-terminated to use a CTE
with CTE (bunchof, columns, Id, ParentId) as
(
select bunchof, columns, Id, ParentId
from @test
where Id = @Id
union all
select a.bunchof, a.columns, a.Id, a.ParentId
from @test as a
inner join CTE as b on a.ParentId = b.Id
)
select * from CTE
Вы также можете выбрать глубину в иерархии, если вам нравятся такие вещи:
declare @Id int
set @Id = 1
;--last statement MUST be semicolon-terminated to use a CTE
with CTE (bunchof, columns, Id, ParentId, Depth) as
(
select bunchof, columns, Id, ParentId, 0
from @test
where Id = @Id
union all
select a.bunchof, a.columns, a.Id, a.ParentId, b.Depth + 1
from @test as a
inner join CTE as b on a.ParentId = b.Id
)
select * from CTE
Как видите, сначала вы выбираете исходный набор записей, который содержит все дочерние строки для параметра родительского идентификатора. Затем вы можете объединиться с другим запросом, который присоединяется к самому CTE, чтобы получить детей детей (и их внуков и т. Д., Пока вы не достигнете последней строки-потомка. Важно отметить, что предел рекурсии по умолчанию равен 100, поэтому платите обращая внимание на глубину иерархии, вы можете изменить предел рекурсии, используя OPTION (MAXRECURSION)
WITH CTE AS (
...
)
SELECT * FROM CTE OPTION (MAXRECURSION 1000)