Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
shurin
Member

Откуда:
Сообщений: 53
Как раскрутить рекурсивную древовидную таблицу (ParentID - ID), Чтобы каждый уровень мог группироваться и являлся атрибутом. Нужно для построения отчетов где требуется древовидное представление, причем на каждом уровне нужно получить итоги.
13 июн 05, 10:34    [1616660]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
Latuk
Member

Откуда: N 54°38', E 037°35'
Сообщений: 7316
Я делал подобное для оборотно сальдовой ведомости
т.е. структура дерева - план счетов и меняется довольно редко.

для начала создается таблица отношений

ID,ParentID
ID,ParentParentID
...
т.е. пары номер узла , Номера всех его предков

Вот сдесь можешь посмотреть как ее сформировать
https://www.sql.ru/forum/actualthread.aspx?bid=1&tid=89883&hl=predok

потом примерно вот так
причем здесь не только сумма вычисляется , но и делается отступ
в зависимости от веса в иерархии, а в отчете еще и размер шрифта меняется
т.к. это была форма для печати
PS_MM_tbl.FinRez содержит результат проводки
на PS_ID_Tree = @Vid можно внимание не обращать
это несколько деревьев из одних и тех же узлов

ALTER PROCEDURE dbo.PS_Rashod_rep
(@BegData smalldatetime,
@EndData smalldatetime,
@Predok int,
@Vid tinyint)

AS 

SELECT     PS_Ves.PS_ID, SPACE((PS_Ves.Ves - 1) * 10) + '' + PS_PlanSchetov.Name AS PS_Name, T.Summa,  PS_Ves.Ves, 
                      Vlt_Valuta.Symvol
FROM         (SELECT     SUM(PS_MM_tbl.FinRez) AS Summa, PS_Predok_1.PS_ID, PS_MM_tbl.Vlt_ID
                       FROM          PS_MM_tbl INNER JOIN
                                              PS_Predok ON PS_MM_tbl.PS_ID = PS_Predok.PS_ID INNER JOIN
                                              PS_Predok PS_Predok_1 ON PS_Predok.PS_ID_Predok = PS_Predok_1.PS_ID INNER JOIN
                                              PS_PlanSchetov ON PS_MM_tbl.PS_ID = PS_PlanSchetov.ID AND PS_MM_tbl.Data >= PS_PlanSchetov.Data
                       WHERE      (PS_Predok.PS_ID_Tree = @Vid) AND (PS_Predok_1.PS_ID_Predok = @Predok) AND (PS_Predok_1.PS_ID_Tree = @Vid) AND 
                                              (PS_MM_tbl.Data BETWEEN @BegData AND @EndData)
                       GROUP BY PS_Predok_1.PS_ID, PS_MM_tbl.Vlt_ID) T INNER JOIN
                      PS_Ves ON PS_Ves.PS_ID = T.PS_ID INNER JOIN
                      PS_PlanSchetov ON PS_Ves.PS_ID = PS_PlanSchetov.ID INNER JOIN
                      Vlt_Valuta ON Vlt_Valuta.ID = T.Vlt_ID
WHERE     (PS_Ves.PS_ID_Tree = @Vid)
ORDER BY PS_Ves.PS_Name_Tree
13 июн 05, 13:18    [1616878]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
shurin
Member

Откуда:
Сообщений: 53
Меняется довольно редко, вложенность? Т.е. она предусматривает константу колличества уровней вложенности?
13 июн 05, 14:52    [1617056]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
Latuk
Member

Откуда: N 54°38', E 037°35'
Сообщений: 7316
>Меняется довольно редко, вложенность?
Значит дерево счетов меняет свою конфигурацию довольно редко
т.е. такой подход давая высокую скорость ответов на "деревянные" вопросы
предусматривает значительные затраты на перестройку дерева

вложенность ограничена размерностью поля PS_Ves.Ves
т.е. практически не ограничена

перемещение узла в дереве из десятка тысячь узлов
с вложенностью порядка 40
происходит за 5-10 сек

т.е. если десяток пользователей начнут активно ворочать положенем узлов
при таком подходе будут проблеммы с производительностью.
13 июн 05, 21:41    [1617611]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
2 Latuk
Как-то у Вас по-моему черезчур сложно сделано. Посмотрел как у меня оборотка делается. По-моему проще. И к тому же практически не ограничено уровнем.

Делается временная таблица, а потом по уровню заносятся нужные данные и считается уровень и поле для порядка сортировки. Если выкинуть лишнее:
declare @ie table(   -- иерархия
  acc int,
  parent int null,
  accstr varchar(55) null,
  lvl INT,
  ord VARCHAR(1000))

INSERT @ie(acc, accstr, lvl, ord)
  SELECT acc, accstr, 0, RIGHT('          '+accstr,10)
    FROM Acc
    WHERE parent IS NULL

WHILE @@rowcount > 0
  INSERT @ie (acc, parent, accstr, lvl, ord)
    SELECT s.acc, s.parent,s.accstr, p.lvl+1, p.ord+RIGHT('          '+s.accstr,10)
      FROM @ie p
      JOIN Acc s ON s.parent=p.acc 
      WHERE not exists(select * from @ie o where s.acc=o.acc)

Т.е. если мы теперь сделаем
select replicare(' ', lvl*2)+accstr from @ie order by ord
мы получим дерево счетов.
Что касается на каждом уровне нужно получить итоги - ну это уже детали

А вобще таблица с иерархией относительно небольшая (врядли больше 100 записей) и на её построение гнаться за милисикендами не стоит.
14 июн 05, 10:39    [1618154]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
shurin
Member

Откуда:
Сообщений: 53
Преобразовал к структуре своей таблицы, стало ругаться

Server: Msg 208, Level 16, State 1, Line 20
Invalid object name 'id'.

Взгляните своим зорким глазом, что не так. У меня не получается


drop table #ie
Create table #ie
( -- иерархия
id char(9),
parentId char(9) null,
descr varchar(55) null,
lvl INT null
-- ord VARCHAR(1000)
)

INSERT #ie (id, parentId, descr, lvl)
SELECT id, parentId ,descr, 0
FROM fort_agro.dbo.SC14252
WHERE parentID = ' 0 '
--select * from #ie


WHILE @@rowcount > 0
begin
INSERT #ie (id, parentId, descr, lvl)

SELECT s.id, s.parentId, s.descr, p.lvl+1
FROM #ie p
left outer JOIN id s ON s.parentId=p.id
WHERE not exists(select * from #ie o where s.id=o.id)
end
select * from #ie
14 июн 05, 15:51    [1619540]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
2 shurin
Очевидно в таблице fort_agro.dbo.SC14252 нет поля id. Но тока вы зря проигнорировали поле ord
14 июн 05, 17:58    [1620052]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
и вот:
left outer JOIN id s ON s.parentId=p.id
14 июн 05, 18:01    [1620064]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
shurin
Member

Откуда:
Сообщений: 53
Т.е. иерархия получается в поле ord? А у меня задача стоит так чтобы, к примеру вложенность: ТМЦ1(Молочные продукты)-ТМЦ2.1(Кефиры) -ТМЦ3.2(Наш молочник) - ТМЦ 4.2 (Домик в деревне) создала иерархию таким образом что-бы на выходе получилось 3 колонки

ТМЦ1 ТМЦ2 ТМЦ3
Молочные продукты Кефиры Наш молочник
Молочные продукты Кефиры Домик в деревне

Стандартная задача, и так мало инфы, нагде ничего нет
15 июн 05, 11:24    [1620968]     Ответить | Цитировать Сообщить модератору
 Re: Раскрутить рекурсивную древовидную таблицу (ParentID - ID) в дерево  [new]
SergSuper
Member

Откуда: SPb
Сообщений: 5488
Ну всё что мог показал, думать за Вас, извините, не могу
15 июн 05, 12:50    [1621309]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить