Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Запрос к дереву


Автор: Ch0bits 18.9.2007, 23:30
Есть таблица с полями: ID, Node и ParentID.
Как получить все листья (узлы без детей) поддерева, заданного узлом Node?
И вообще есть ли какие-нибудь специальные средства для запросов к иерархическим таблицам?

Автор: dereyly 19.9.2007, 16:24
Вот рекурсивная процедурка, но можно и просто составить запрос с параметром
Код

CREATE PROCEDURE proc_derevo
(
    @id int
)
AS
BEGIN
    SET NOCOUNT ON;
    with recurse(ID,ParentID,Node)
    as
    (
    select a.ID,a.ParentID,a.Node
    from [oks].[dbo].[Razdel] a
    where a.ID=@id
    union all
    select a.ID,a.ParentID,a.Node
    from [oks].[dbo].[Razdel] a
    inner join
    recurse b
    on b.ID=a.ParentID
    )
-- мой select
    select c.*
    from recurse b
    inner join
    [oks].[dbo].[Tovar] c
    on b.ID=c.ID;
END
GO

PS: писал на SQL 2005, но на 2000 тож длжно вроде работать
PSS: или сами узлы с детьми не должны отображатся? 

Автор: Ch0bits 19.9.2007, 16:40
Забыл упомянуть об одной проблеме. Я не могу изменять базу, т.е. не могу создать хранимую процедуру. Единственное что можно - один select.
Но все равно +1 за старание.

Автор: VOS 1.10.2007, 16:14
Попробуйте такой вариант, он без рекурсии, но с ограничением на кол-во вложений.
Получает меню в иерархическом виде (максимум 25 уровней вложенности)
Если уровней больше, то увеличить srt varbinary (100) кратно 4-м 
Для 100 уровней srt varbinary(400)
Работает шустро smile

Код

declare @root int
declare  @tree TABLE (id int, parent int, [name] varchar(100),  [level] int,  srt varbinary(100))
declare @level int 
--Поддерево
set @root=0
set @level = 0
insert @tree (id, parent, [name],[level], srt)  select @root, null,'', @level, cast(0 as varbinary(4))

 while 1=1
       begin
                insert @tree (id, parent, [name],[level], srt)  select tr.ID, tr.Parent, tr.name, @level + 1,  t.srt + CAST(tr.id AS varbinary(4))   from menu as tr   join @tree as t on t.id = tr.Parent and t.level = @level 
                if @@rowcount = 0 break
                set @level = @level + 1
      end
  delete from @tree where id=@root

select * from @tree order by srt

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)