Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как получить иерархичные данные?  [new]
Igram
Member

Откуда:
Сообщений: 9
Доброго дня!
Столкнулся с проблемой. длительное время не могу решить.
Есть таблица. в числе полей которых есть Id и ParentId. первое хранит ид предприятия, второе ид предприятия, которому оно подчинено(данные хранятся в той же таблице). понятно, что у предприятия может быть сложная иерархия - например ему может быть подчинено несколько предприятий, которым могут подчинятся еще какие-то. Задача - достать полную иерархию подчиненных предприятий для заданного.

Идеи которые рассмотрел:
1. Временная таблица. В нее положить заданное ИД предприятия, для которого ищем сначало подченные ему, потом подчиненные этим подчиненным. По ходу нахождения допихивать найденное во временную таблицу.
Проблема - не смог придумать как перебирать. Технических идей не приходит.
2. Рекурсия.
Проблема - как юзать данные которые вновь находятся, чтобы убедится, что они - конечны и не являются ни для кого родителями?

Прочитанные статьи:
http://msdn.microsoft.com/ru-ru/library/bb630263.aspx
http://www.comprog.ru/OtherOfDatabases/article_3793.htm

я либо не понимаю решения, либо это не про то

Заранее спасибо за любую помощь в т.ч. ссылки на похожую задачу :)
26 июл 11, 16:31    [11029448]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Igram
2. Рекурсия.
Проблема - как юзать данные которые вновь находятся, чтобы убедится, что они - конечны и не являются ни для кого родителями?

как-то так?
... WHERE NOT EXISTS(SELECT ... WHERE t2.id = t1.parentId)
26 июл 11, 16:35    [11029476]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31978
Igram
Прочитанные статьи:
http://msdn.microsoft.com/ru-ru/library/bb630263.aspx
http://www.comprog.ru/OtherOfDatabases/article_3793.htm

я либо не понимаю решения, либо это не про то
Первая ссылка как раз про то.

Там рассматривается способ получения иерархии одним запросом, без рекурсии и без перебора записей.
26 июл 11, 16:38    [11029508]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Igram
Member

Откуда:
Сообщений: 9
проблема как раз в многоточиях. ясно, что нужны какие-то структуры для хранения результатов
CREATE FUNCTION ChilrenNodes (@Parent Integer) RETURNS TABLE AS
RETURN(SELECT Id FROM Ent
WHERE ParentId = @Parent)
как ее вызвать, чтоб она копила данные?
26 июл 11, 16:40    [11029525]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Igram
Member

Откуда:
Сообщений: 9
alexeyvg
Igram
Прочитанные статьи:
http://msdn.microsoft.com/ru-ru/library/bb630263.aspx
http://www.comprog.ru/OtherOfDatabases/article_3793.htm

я либо не понимаю решения, либо это не про то
Первая ссылка как раз про то.

Там рассматривается способ получения иерархии одним запросом, без рекурсии и без перебора записей.



Согласен это что надо если скопипастить и подшлифовать. Однако я в попыхах забыл указать что у меня есть ограничение что скрипт могут пустить и на 2000 sql, а в BOL(перевод стать оттуда http://www.sqlbooks.ru/readarticle.aspx?part=02&file=sql200514) написано что эти чудесные функции появились только в 2005.

PS почитал для общего развития чего за такие OVER PARTITION тоже в боле честно плохо понял.
Если есть время и возможность помочь мне в борьбе с моей тупостью, не могли бы Вы объяснить что они делают?
26 июл 11, 17:06    [11029736]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
PVC
Member

Откуда:
Сообщений: 319
Igram,

в свое время мы заткнули эту проблему, добавив в комплект к ID и ParentID поле RootID. В нем по всем уровням насквозь прописывается ID родителя верхнего уровня.
26 июл 11, 17:09    [11029765]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Igram
Member

Откуда:
Сообщений: 9
PVC,
Да, это действительно хороший вариант. Задача облегчается в разы. Однако мне не разрешено трогать структуру таблиц. Она затрагивает несколько проектов и на нее завязан программный код. Да и решаемая мной задача носит вспомогательный характер. Менеджер моих покушений на структуру не одобрит :)
26 июл 11, 17:32    [11029933]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
PVC
Member

Откуда:
Сообщений: 319
Igram,

..ну тогда Вас ждут безумные рекурсии :) что то типа такого

--@id - это текущий ид
insert @id into @tmp
while 1=1 begin
  insert into @tmp 
  select id 
  from MyTable MT
  join @tmp T1 on T1.Id=MT.ParentId
  left join @tmp T on T.ID=MT.ID
  where T.ID is NULL
  if @@rowcount=0 break
end
26 июл 11, 17:43    [11029999]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31978
Igram
Согласен это что надо если скопипастить и подшлифовать. Однако я в попыхах забыл указать что у меня есть ограничение что скрипт могут пустить и на 2000 sql, а в BOL(перевод стать оттуда http://www.sqlbooks.ru/readarticle.aspx?part=02&file=sql200514) написано что эти чудесные функции появились только в 2005.
Тогда можно поискать на этом форуме:

Помогите с запросом. Иерархия. Дерево.
или
Подскажите, пожалуйста, как в MSSQL реализовать иерархический запрос

Igram
PS почитал для общего развития чего за такие OVER PARTITION тоже в боле честно плохо понял.
Если есть время и возможность помочь мне в борьбе с моей тупостью, не могли бы Вы объяснить что они делают?
А смысл? Их тоже нету в 2000-ом :-(
26 июл 11, 17:48    [11030036]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
PVC
Member

Откуда:
Сообщений: 319
Igram,

поправлю, накосячил

--@id - это текущий ид
declare @tmp table(id int)
insert into @tmp(id) select @id 
while 1=1 begin
  insert into @tmp 
  select MT.id 
  from MyTable MT
  join @tmp T1 on T1.Id=MT.ParentId
  left join @tmp T on T.ID=MT.ID
  where T.ID is NULL
  if @@rowcount=0 break
end
26 июл 11, 18:15    [11030182]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31978
PVC
Igram,

поправлю, накосячил

--@id - это текущий ид
declare @tmp table(id int)
insert into @tmp(id) select @id 
while 1=1 begin
  insert into @tmp 
  select MT.id 
  from MyTable MT
  join @tmp T1 on T1.Id=MT.ParentId
  left join @tmp T on T.ID=MT.ID
  where T.ID is NULL
  if @@rowcount=0 break
end
Всё равно неправильно :-)

Лучьше посмотрите ссылки, которые я дал.
26 июл 11, 18:19    [11030207]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
PVC
Member

Откуда:
Сообщений: 319
alexeyvg,

почему неправильно? должно работать, однако.
а ссылки - это ТС нужно.
26 июл 11, 18:27    [11030242]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Bobby
Member

Откуда:
Сообщений: 638
Igram,

Доброго дня. Посмотрите вот это. какое-то время назад делал нечто подобное.
ALTER FUNCTION [dbo].[fn_child_nodes_part]
(@id_obj INT)
RETURNS 
@temp_id  TABLE (id_parent INT)
AS
BEGIN 

  DECLARE @row INT
  DECLARE  @temp_id1 TABLE  (id_parent INT) 
  DECLARE  @temp_id2 TABLE  (id_parent INT)
  INSERT INTO @temp_id (id_parent) values(@id_obj)
  INSERT INTO @temp_id1
  SELECT id_obj FROM people_group WHERE id_parent in(SELECT * FROM @temp_id)   
  SET @row=@@ROWCOUNT

  WHILE @row<>0
  BEGIN
    INSERT INTO @temp_id2 SELECT id_obj FROM people_group WHERE id_parent IN(SELECT * FROM @temp_id1)
    SET @row=@@ROWCOUNT
    INSERT INTO @temp_id SELECT * FROM @temp_id1
    DELETE FROM @temp_id1
    INSERT INTO @temp_id1 SELECT * FROM @temp_id2
    DELETE FROM @temp_id2
  END
RETURN
END

создается memo-таблица, где вся иерархия для заданного узла. что-то типа такого
26 июл 11, 20:25    [11030669]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Igram
Member

Откуда:
Сообщений: 9
Клево!
Последние ответы очень помогли. сложил их вместе. подогнал под задачу и все стало ништяк. Спасибо огромное всем за уделенное время, четкие ответы и реальную помощь :)
27 июл 11, 17:37    [11035748]     Ответить | Цитировать Сообщить модератору
 Re: Как получить иерархичные данные?  [new]
Natalet
Member

Откуда:
Сообщений: 59
а можете написать Ваш результирующий запрос? у меня аналогичная проблема. тоже подразделения в предприятии) буду очень признательна за помощь!
23 ноя 11, 15:42    [11645542]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить