powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Работа с деревом
7 сообщений из 7, страница 1 из 1
Работа с деревом
    #32062376
Dmitry Frolov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть древовидная структура ID, ParentID
Как получить запросом - некоторую запись по
известному ID и всех ее потомков?
...
Рейтинг: 0 / 0
Работа с деревом
    #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
Работа с деревом
    #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
Работа с деревом
    #32062397
Александр Азаркович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем случае - когда число уровней иерархии не ограничено - есть два пути: или рекурсивная фукнция, или оптимизационное поле, в которое выписываете, например, коды всех предков элемента, через какой-то разделитель, а ищете - LIKE'ом. Есть другие красивые методы оптимизации, но уж очень много времени на каждое изменение в дереве...
...
Рейтинг: 0 / 0
Работа с деревом
    #32062399
fima
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще, про работу с деревьями можно почитать здесь: http://sdm.viptop.ru/articles/sqltrees.html, да и на www.sql.ru поискать можете, очень много писалось...
...
Рейтинг: 0 / 0
Работа с деревом
    #32071986
Фотография Calm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно ли получить путь в дереве от некоторого листа (или просто узла) до корня?
Если можно, то, пожалуйста. напишите, как это сделать.
...
Рейтинг: 0 / 0
Работа с деревом
    #32072083
fima
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно. Вам надо, соответственно, выбирать не потомков для глав последнего уровня, как в примере, а наоборот, выбирать родителя (или родителей, это уж от условий задачи) для глав последнего уровня.
Удачи.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Работа с деревом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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