PDA

View Full Version : بدست آوردن گره های زيرشاخه (در روش Adjacency list model)



FSarab
یک شنبه 10 آبان 1388, 16:11 عصر
ميخوام با يك دستور select از اين جدول كه داراي ساختار درختي است


CREATE TABLE [dbo].[ATest]
(
[FID] [int] IDENTITY (1, 1) NOT NULL ,
[FParentID] [int] NULL ,
[FName] [varchar] (50) COLLATE Arabic_CI_AS NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[ATest] WITH NOCHECK ADD
CONSTRAINT [PK_ATest] PRIMARY KEY CLUSTERED
(
[FID]
) ON [PRIMARY]
GO


insert into ATest(FParentID, FName) values(null, 'A')
insert into ATest(FParentID, FName) values(1, 'B')
insert into ATest(FParentID, FName) values(2, 'C')
insert into ATest(FParentID, FName) values(3, 'D')
insert into ATest(FParentID, FName) values(4, 'E')
insert into ATest(FParentID, FName) values(null, 'AA')
insert into ATest(FParentID, FName) values(6, 'BB')
insert into ATest(FParentID, FName) values(7, 'CC')


با داشتن FID = 1 ميخوام با يك دستور select اين نتيجه بدست بيارم

FID FName
----------- ---------
1 A
2 B
3 C
4 D
5 E

محمد سلیم آبادی
یک شنبه 10 آبان 1388, 17:31 عصر
set nocount on

declare @tree table
(
node char(2) primary key,
parent char(2)
)

insert into @tree values
--Tree A
('a', null), ('b', 'a'), ('c', 'b'), ('d', 'c'),('e', 'd'),
--Tree B
('aa', null), ('bb', 'aa'), ('cc', 'aa')

declare @a table (a char(2), b bit, l int)
insert into @a
select 'a', 1, 1 --Tree A

declare @l int
select @l=l from @a

while @@rowcount>0
begin
set @l=@l+1
insert into @a
select node, 1, @l from @tree where parent in (select a from @a where b=1)
update @a set b=0 where l=@l-1
end

select a as node, l as level from @a
/*
node level
---- -----------
a 1
b 2
c 3
d 4
e 5
*/

مهدی نان شکری
یک شنبه 10 آبان 1388, 22:11 عصر
با سلام
نمی دونم منظورتون رو درست متوجه شدم یا نه ولی این رو تست کنید ببینید درسته؟


with mycte(FID,FParentID,FName)
as
(
select FID,FParentID,FName from Atest Where FID = 1
Union ALL
Select Atest.FID,Atest.FParentID,Atest.FName from Atest Join mycte on Atest.FParentID=mycte.FId
)
select * from mycte

محمد سلیم آبادی
چهارشنبه 04 آذر 1388, 12:06 عصر
سلام،
اگر منظورتان از جمله ی "با یک دستور Select..." این باشد که دنبال یک روش set-based می گردین، query زیر یک راه حل است.
برای حل اینگونه مسائل ما نیاز داریم که از حلقه و بازگشت استفاده کنیم و تعداد بازگشت وابسته به تعداد سطوح درخت است و تعداد سطوح درخت متغیر است پس روش پیشرو زمانی می تواند مورد استفاده قرار بگیرد که تعداد سطوح درخت محدود و مشخص باشد.



declare @t table (node char(1), parent char(1))
insert into @t values ('a', null)
insert into @t values ('b', 'a')
insert into @t values ('e', 'a')
insert into @t values ('c', 'b')

/*
a
/ \
b e
|
c
*/

select 'a' as node
union all
select t1.node
from @t t1
inner join (select 'a') as t2 (node)
on t1.parent = t2.node
union all
select t1.node
from @t t1
inner join (select t1.node
from @t t1
inner join (select 'a') as t2 (node)
on t1.parent = t2.node) as t2 (node)
on t1.parent = t2.node