Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Работа с деревом / 7 сообщений из 7, страница 1 из 1
28.10.2002, 15:17:31
    #32062376
Dmitry Frolov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
Есть древовидная структура ID, ParentID
Как получить запросом - некоторую запись по
известному ID и всех ее потомков?
...
Рейтинг: 0 / 0
28.10.2002, 15:48:17
    #32062391
fima
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
Вот пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
 /* таблица с примером оглавления книги */ 
if exists (select * from sysobjects
		where name = 'Chapters' and
			type = 'U')
begin
	drop table Chapters
end
create table Chapters
(
	ID_Chapter integer identity not null,
	[Name] varchar ( 32 ) not null,
	ID_Parent_Chapter integer null,
	constraint pk_Chapters primary key (ID_Chapter),
	constraint fk_Chapters__Child_Chapters foreign key (ID_Parent_Chapter)
		references Chapters (ID_Chapter)
)
go
set identity_insert Chapters on
go
 /* тестовые примеры */ 
insert into Chapters (ID_Chapter, [Name], ID_Parent_Chapter)
values ( 1 , 'Глава 1', null)
insert into Chapters (ID_Chapter, [Name], ID_Parent_Chapter)
values ( 2 , 'Глава 1.1',  1 )
insert into Chapters (ID_Chapter, [Name], ID_Parent_Chapter)
values ( 3 , 'Глава 1.1.1',  2 )
insert into Chapters (ID_Chapter, [Name], ID_Parent_Chapter)
values ( 4 , 'Глава 1.1.1.1',  3 )
insert into Chapters (ID_Chapter, [Name], ID_Parent_Chapter)
values ( 5 , 'Глава 1.1.1.1.1',  4 )
go
 /* процедура выбора глава */ 
if exists (select * from sysobjects where type = 'P' and name = 'Get_Chapters')
begin
	drop procedure Get_Chapters
end
go
create procedure Get_Chapters
(
	@ID_Chapter integer  -- ид узла который вместе с потомками хотим вывести
 
)
as
declare @Level integer,
	@Count_Chapter integer,
	@Error_Code integer
begin
	 /* временная таблица */ 
	create table #stack
	(
		[Name] varchar ( 32 ),
		[Level] int,
		ID_Chapter int
	)
	 /* занесение первой главы которую хотим получить */ 
	set @Level =  1 
	insert into #stack 
	select [Name], @Level, ID_Chapter
	from Chapters
	where ID_Chapter = @ID_Chapter
	select @Count_Chapter = @@rowcount, @Error_Code = @@error
	if @Error_Code <>  0  or @Count_Chapter <>  1 
	begin
		return (- 1 )
	end
	else
	begin
		 /* цикл по потомкам главы пока они есть */ 
		while @Count_Chapter <>  0 
		begin
			set @Level = @Level +  1 
			insert into #stack select [Name], @Level, ID_Chapter
			from Chapters
			where Chapters.ID_Parent_Chapter in (select ID_Chapter from #stack
				where [Level] = @Level -  1 )
			select @Count_Chapter = @@rowcount, @Error_Code = @@error
			if @Error_Code <>  0 
			begin
				return (- 2 )
			end
		end
		 /* выбор из временной таблицы */ 
		select * from #stack
	end
end
go
exec Get_Chapters  1 
Result:
Name                             Level       ID_Chapter  
 -------------------------------- ----------- ----------- 
 
Глава  1                            1             1 
Глава  1 . 1                          2             2 
Глава  1 . 1 . 1                        3             3 
Глава  1 . 1 . 1 . 1                      4             4 
Глава  1 . 1 . 1 . 1 . 1                    5             5 

Если что непонятно, пишите.
...
Рейтинг: 0 / 0
28.10.2002, 15:53:32
    #32062396
Kilroy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
[src][/src]

select into #tmp
id from <table>
where parentid = @id --где @id корень ветки

while @@rowcount <>0
begin

insert #tmp
select id
from <table> t1 join #tmp t2 on t1.parentid = t2.id
end

--Теперь в #tmp id узлов всей ветки
select id from #tmp
drop table #tmp
...
Рейтинг: 0 / 0
28.10.2002, 15:54:29
    #32062397
Александр Азаркович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
В общем случае - когда число уровней иерархии не ограничено - есть два пути: или рекурсивная фукнция, или оптимизационное поле, в которое выписываете, например, коды всех предков элемента, через какой-то разделитель, а ищете - LIKE'ом. Есть другие красивые методы оптимизации, но уж очень много времени на каждое изменение в дереве...
...
Рейтинг: 0 / 0
28.10.2002, 16:01:31
    #32062399
fima
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
И еще, про работу с деревьями можно почитать здесь: http://sdm.viptop.ru/articles/sqltrees.html, да и на www.sql.ru поискать можете, очень много писалось...
...
Рейтинг: 0 / 0
25.11.2002, 14:27:04
    #32071986
Calm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
А можно ли получить путь в дереве от некоторого листа (или просто узла) до корня?
Если можно, то, пожалуйста. напишите, как это сделать.
...
Рейтинг: 0 / 0
25.11.2002, 16:36:08
    #32072083
fima
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с деревом
Можно. Вам надо, соответственно, выбирать не потомков для глав последнего уровня, как в примере, а наоборот, выбирать родителя (или родителей, это уж от условий задачи) для глав последнего уровня.
Удачи.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Работа с деревом / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]