![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Рекурсивная выборка из таблицы со структурой дерева [D7, MSSQL]
kotyara12 © (2008-04-03 22:01:00)Есть таблица (дерево), поля ID (ключ), OWNER_ID (ID записи "родителя"), NAME.... и так далее. Для "корневых" записей OWNER_ID = NULL.
Нужно для прозвольного ID выбрать саму указанную запись плюс все записи родителей вплоть до корневой.
Т.е. должно быть примерно следующее:
ID OWNER_ID NAME
1 (NULL) корневая запись
23 1 1-ый уровень
107 23 2-ой уровень
и т.д.....
Понимаю, что должна быть какая-то рекурсия, но как это реализовать на MS SQL (2000)?
Johnmen (2008-04-11 20:30:00) [1]
> Но самый простой способ - юзать для деревьев оракл.
Ага. Для лечения гиморроя он тоже годится.
ANB (2008-04-11 18:19:00) [2]Я на клиппере писал обход дерева без рекурсии.
Но самый простой способ - юзать для деревьев оракл. Простым селектом сам все обходит - хошь вверх, хош вниз.
evvcom (2008-04-11 10:27:00) [3]
> Ega23 © (04.04.08 10:06) [8]
> Интересный приёмчик...
> Запомню.. :)
Я такой уже лет несколько от того же автора здесь же сфотографировал :) Кстати, тогда он был причесан, приведена только суть )
> OWNER_ID (ID записи " родителя")
Если это родитель, то почему поле называется не PARENT_ID или ID_PARENT? Причем здесь "владелец"?
Ega23 (2008-04-04 10:06:00) [4]Интересный приёмчик...
Запомню.. :)
sniknik (2008-04-04 08:43:00) [5]> Задача обхода дерева от корня к листу решается рекурсией.
тоже можно "простым" while
не буду "подгонять", как есть из проекта, думаю и так понятно будет
DECLARE @Dep INT
DECLARE @Lvl INT
DECLARE @Rc INT
SET @Dep=:Dep
SET @Lvl=1
DECLARE @Tbl TABLE (ID INT PRIMARY KEY CLUSTERED,PID INT NULL,Lvl INT NOT NULL)
INSERT @tbl (ID,PID,Lvl) SELECT ID,PID,@Lvl FROM Department where PID=@Dep
SET @Rc=@@RowCount
WHILE @Rc>0 BEGIN
SET @Lvl=@Lvl+1
INSERT @Tbl (ID,PID,Lvl) SELECT d.ID, d.PID, @Lvl FROM @Tbl t INNER JOIN Department d on t.ID=d.PID WHERE t.Lvl=@Lvl-1
SET @Rc=@@RowCount
END
INSERT @tbl (ID,PID,Lvl) VALUES (@Dep, 0, 0)
SELECT
e.ID,
isNull(d.Name,'') AS 'Äåïàðòàìåíò',
isNull(h.Name,'') AS 'Îáîðóäîâàíèå',
isNull(m.Name,'') AS 'Ñîîáùåíèå',
isNull(m.State,0) AS 'Ñòàòóñ',
ServDate AS 'Âðåìÿ ñîáûòèÿ'
FROM Event e
LEFT JOIN Department d ON e.IDDepartment=d.ID
LEFT JOIN Hard h ON e.IDHard=h.ID
LEFT JOIN Message m ON e.IDDrvType=m.IDDrvType AND e.Code=m.Code
WHERE (e.IDDepartment IN (SELECT ID FROM @Tbl)) AND (e.ServDate BETWEEN @DWith AND @DTo+1) AND (m.State IN (@St1,@St2,@St3) )
ORDER BY e.ID
собственно интересующий цикл в начале, последний селект это уже выборка по набранным в "рекурсии" ключам и доп. условиям полных записей (можно не рассматривать).
Ega23 (2008-04-04 08:28:00) [6]
> А.. ну да... временные таблицы.
при чём тут временные таблицы?
задача обхода дерева от листа к корню (какоиу-то родителю) решается простым while. Задача обхода дерева от корня к листу решается рекурсией.
ага (2008-04-04 07:38:00) [7]
> Ega23 © (04.04.08 01:01) [3]
А.. ну да... временные таблицы.
kotyara12 (2008-04-04 07:22:00) [8]
> Ega23 © (04.04.08 01:01) [3]
Сенкс...., то что надо!
Ega23 (2008-04-04 01:01:00) [9]
> Ega23 © (04.04.08 00:59) [2]
блин, долбаная мышка...
Часть запроса "съелась"
create procedure MyProc
@ID int =null
as
select id, owner_id, name
into #temp
from Table
where id=@id;
while(@ID is not null)
begin
select @ID=owner_id
from Table
where ID=@ID;
select id, owner_id, name
into #temp
from Table
where id=@id;
end;
Select * from #temp;
return(0);
GO
Ega23 (2008-04-04 00:59:00) [10]
> Понимаю, что должна быть какая-то рекурсия, но как это реализовать
> на MS SQL (2000)?
> ага (03.04.08 22:19) [1]
>
>
> > kotyara12 (03.04.08 22:01)
>
> рекурсивная ХП.
>
Смеетесь?
create procedure MyProc
@ID int =null
as
while(@ID is not null)
begin
select @ID=owner_id
from Table
where ID=@ID;
select id, owner_id, name
into #temp
from Table
where id=@id;
end;
Select * from #temp;
return(0);
GO
ага (2008-04-03 22:19:00) [11]
> kotyara12 (03.04.08 22:01)
рекурсивная ХП.