Форум: "Базы";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
ВнизПодскажите с запросом sql Найти похожие ветки
← →
Vlad Oshin © (2007-12-25 18:04) [0]Имеется набор объектов, каждый из которых характеризуется следующим:
1. уникальностью (id )
2. возможностью содержать в себе другие объекты (isfolder. 1-контейнер, 2-просто объект)
3. признаком содержания себя самого в объекте (parentid=id контейнера в котором содержится. Контейнер может быть в контейнере)
Задача - получить все объекты, из указанного контейнера, на всю глубину, т.е. из всех вложенных контейнеров, из вложенных во вложенные и т.д. Только одни объекты(isfolder=2)
ничего умнее не приходит следующего:
select DESCR, ID from SC46 where
(isfolder=2 and parentid=" 1VJ ")
(isfolder=2 and parentid in
(select id from SC46 where isfolder=1 and parentid =" 1VJ "))
(isfolder=2 and parentid in
(select id from SC46 where isfolder=1 and parentid in
(select id from SC46 where isfolder=1 and parentid =" 1VJ ")))
(isfolder=2 and parentid in
(select id from SC46 where isfolder=1 and parentid in
(select id from SC46 where isfolder=1 and parentid in
(select id from SC46 where isfolder=1 and parentid =" 1VJ "))))
....
при очередном запросе даст ноль, значит докопались
← →
clickmaker © (2007-12-25 18:09) [1]рекурсия, что-ль?
declare @Current_ID int
declare @TreeLevel int
declare @Stack table (Object_ID int null, TreeLevel int)
declare @Results table (Object_ID int null)
select @Current_ID = @Object_ID
select @TreeLevel = 1
insert into @Stack values (@Current_ID, @TreeLevel)
while @TreeLevel > 0 begin
if exists (select * from @Stack where TreeLevel = @TreeLevel) begin
select top 1 @Current_ID = Object_ID from @Stack where TreeLevel = @TreeLevel
insert into @Results (Object_ID) values (@Current_ID)
delete from @Stack where TreeLevel = @TreeLevel and Object_ID = @Current_ID
if @Type is not null
insert into @Stack
select Object_ID, @TreeLevel + 1
from Objects
where Parent_ID = @Current_ID and Type = @Type
else
insert into @Stack
select Object_ID, @TreeLevel + 1
from Objects
where Parent_ID = @Current_ID
if @@rowcount > 0
select @TreeLevel = @TreeLevel + 1
end
else
select @TreeLevel = @TreeLevel - 1
end
delete from @Results where Object_ID = @Object_ID
select r.Object_ID
from @Results r
← →
Ketmar_ (2007-12-25 18:48) [2]а говорят «декларативный, декларативный»…
← →
sniknik © (2007-12-25 20:55) [3]clickmaker © (25.12.07 18:09) [1]
имхо, с удалениями перебор... т.к. операция "тяжелая".
по идее мой вариант должен быть быстрее (но проверять не буду. нафиг)DECLARE @ID INT
DECLARE @Lvl INT
DECLARE @Rc INT
SET @ID=1 -- задается с которой записи выборка. сама не выбирается, только "детки"
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 MainTable where PID=@ID
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 MainTable d on t.ID=d.PID
WHERE t.Lvl=@Lvl-1
SET @Rc=@@RowCount
END
SELECT ID FROM @Tbl
в "главной" таблице
ID - это ID
PID - ну это "парент" ID (желательно присутствие индекса по нему)
в выборке
Lvl - это уровень, т.е. если нужны не все а например только третий(или другой) уровень то по нему можно условие в последнем селекте задать.
еще у корневых записей "парент" у меня не null как обычно, а 0, что позволяет не меняя ничего выбирать и из корня (если тут не так, то вариант выборки начиная с "корня" не пройдет).
← →
Кщд (2007-12-26 06:09) [4]
> Vlad Oshin © (25.12.07 18:04)
если, вдруг, Oracle, то connect by
← →
Vlad Oshin © (2007-12-26 09:45) [5]ага..
спасибо
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2008.06.01;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.046 c