Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.12;
Скачать: CL | DM;

Вниз

Рекурсивная выборка из таблицы со структурой дерева   Найти похожие ветки 

 
kotyara12   (2008-04-03 22:01) [0]

Есть таблица (дерево), поля ID (ключ), OWNER_ID (ID записи "родителя"), NAME.... и так далее. Для "корневых" записей OWNER_ID = NULL.
Нужно для прозвольного ID выбрать саму указанную запись плюс все записи родителей вплоть до корневой.
Т.е. должно быть примерно следующее:
ID      OWNER_ID     NAME
1       (NULL)          корневая запись
23      1                 1-ый уровень
107     23               2-ой уровень
и т.д.....
Понимаю, что должна быть какая-то рекурсия, но как это реализовать на MS SQL (2000)?


 
ага   (2008-04-03 22:19) [1]


> kotyara12   (03.04.08 22:01)

рекурсивная ХП.


 
Ega23 ©   (2008-04-04 00:59) [2]


> Понимаю, что должна быть какая-то рекурсия, но как это реализовать
> на 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


 
Ega23 ©   (2008-04-04 01:01) [3]


> 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


 
kotyara12   (2008-04-04 07:22) [4]


> Ega23 ©   (04.04.08 01:01) [3]

Сенкс...., то что надо!


 
ага   (2008-04-04 07:38) [5]


> Ega23 ©   (04.04.08 01:01) [3]


А.. ну да... временные таблицы.


 
Ega23 ©   (2008-04-04 08:28) [6]


> А.. ну да... временные таблицы.


при чём тут временные таблицы?
задача обхода дерева от листа к корню (какоиу-то родителю) решается простым while. Задача обхода дерева от корня к листу решается рекурсией.


 
sniknik ©   (2008-04-04 08:43) [7]

> Задача обхода дерева от корня к листу решается рекурсией.
тоже можно "простым" 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,"<&#205;&#229; &#237;&#224;&#233;&#228;&#229;&#237;>") AS "&#196;&#229;&#239;&#224;&#240;&#242;&#224;&#236;&#229;&#237;&#242;",
   isNull(h.Name,"<&#205;&#229; &#237;&#224;&#233;&#228;&#229;&#237;>") AS "&#206;&#225;&#238;&#240;&#243;&#228;&#238;&#226;&#224;&#237;&#232;&#229;",
   isNull(m.Name,"<&#205;&#229; &#237;&#224;&#233;&#228;&#229;&#237;>") AS "&#209;&#238;&#238;&#225;&#249;&#229;&#237;&#232;&#229;",  
   isNull(m.State,0) AS "&#209;&#242;&#224;&#242;&#243;&#241;",  
   ServDate AS "&#194;&#240;&#229;&#236;&#255; &#241;&#238;&#225;&#251;&#242;&#232;&#255;"
 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 10:06) [8]

Интересный приёмчик...
Запомню.. :)


 
evvcom ©   (2008-04-11 10:27) [9]


> Ega23 ©   (04.04.08 10:06) [8]
> Интересный приёмчик...
> Запомню.. :)

Я такой уже лет несколько от того же автора здесь же сфотографировал :) Кстати, тогда он был причесан, приведена только суть )


> OWNER_ID (ID записи "родителя")

Если это родитель, то почему поле называется не PARENT_ID или ID_PARENT? Причем здесь "владелец"?


 
ANB   (2008-04-11 18:19) [10]

Я на клиппере писал обход дерева без рекурсии.

Но самый простой способ - юзать для деревьев оракл. Простым селектом сам все обходит - хошь вверх, хош вниз.


 
Johnmen ©   (2008-04-11 20:30) [11]


> Но самый простой способ - юзать для деревьев оракл.

Ага. Для лечения гиморроя он тоже годится.



Страницы: 1 вся ветка

Текущий архив: 2008.10.12;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.016 c
2-1220237788
FIL-23
2008-09-01 06:56
2008.10.12
Сортировка масива


2-1220262994
gln
2008-09-01 13:56
2008.10.12
Прокрутка RichEdit


15-1219226478
silver222
2008-08-20 14:01
2008.10.12
Вывод фотографий


15-1219235641
sD
2008-08-20 16:34
2008.10.12
динамическое создание форм


2-1220437821
Term
2008-09-03 14:30
2008.10.12
AdvStringGrid