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

Откуда: Ростов-на-Дону
Сообщений: 312
Andrey Pogorelov
Привет всем.
Имеется таблица с древовидной структурой
id, par_id, level, sum
1,   0,       1,     800
2,   1,       2,     300  
3,   1,       2,     100
4,   1,       2,     400
5,   2,       3,     100
6,   5,       4,      50
7,   5,       4,      50
8,   4,       3,     200
9,   4,       3,     200

800
   |->300
        |-> 100
              |-> 50
              |-> 50
   |->100
   |->400
        |-> 200
        |-> 200
Необходимо пройтись по веткам дерева и собрать значение sum для каждого родителя.
4 авг 09, 07:29    [7493356]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Andrey Pogorelov
Member

Откуда: Ростов-на-Дону
Сообщений: 312
Забыл добавить база на Sql Server 2005
4 авг 09, 07:48    [7493369]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 33354
Блог
и где ваш вариант? или надо сделать за вас?

ps в работу такие темы надо
4 авг 09, 07:54    [7493374]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Andrey Pogorelov
Member

Откуда: Ростов-на-Дону
Сообщений: 312
Критик,
Меня б на правильные рельсы поставить, что то ума не приложу с чего начать.
4 авг 09, 08:06    [7493385]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Andrey Pogorelov
Критик,
Меня б на правильные рельсы поставить, что то ума не приложу с чего начать.
Начать с поиска...
4 авг 09, 08:06    [7493387]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Andrey Pogorelov
Member

Откуда: Ростов-на-Дону
Сообщений: 312
Что-то не могу найти инфу по данному вопросу, ткните носом, лучше в пример.
Заранее большое спасибо.
4 авг 09, 09:34    [7493638]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Andrey Pogorelov
Что-то не могу найти инфу по данному вопросу, ткните носом, лучше в пример.
Заранее большое спасибо.
Ну, хотя б сюда - https://www.sql.ru/articles/Publications.shtml#062 загляните.
4 авг 09, 09:36    [7493652]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Если хочется с CTE повозиться (не проверял, но, может, это будет тормозить по сравнению с другими решениями), то
USE tempdb;
SET NOCOUNT ON;
IF OBJECT_ID(N'T','U')IS NOT NULL DROP TABLE T;
CREATE TABLE T(id int, par_id int, level int, [sum] int);
INSERT T(id, par_id, level, [sum])
          SELECT 1,   0,       1,     800
UNION ALL SELECT 2,   1,       2,     300  
UNION ALL SELECT 3,   1,       2,     100
UNION ALL SELECT 4,   1,       2,     400
UNION ALL SELECT 5,   2,       3,     100
UNION ALL SELECT 6,   5,       4,      50
UNION ALL SELECT 7,   5,       4,      50
UNION ALL SELECT 8,   4,       3,     200
UNION ALL SELECT 9,   4,       3,     200;

WITH Tree(id,[path],[sum]) AS
(
 SELECT T.id, CAST(STR(T.id,11)AS VARCHAR(MAX)), T.[sum] FROM T WHERE NOT EXISTS(SELECT * FROM T TT WHERE TT.id=T.par_id)
 UNION ALL
 SELECT T.id, Tree.[path]+STR(T.id,11), T.[sum] FROM T JOIN Tree ON T.par_id=Tree.id
)
SELECT Tree.id, (SELECT SUM(TT.[sum]) FROM Tree TT WHERE TT.[path] LIKE Tree.[path]+'%')[sum]
FROM Tree
ORDER BY Tree.id;

IF OBJECT_ID(N'T','U')IS NOT NULL DROP TABLE T;
Подсчитанные суммы включают сам узел и всех его потомков.
4 авг 09, 10:07    [7493818]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Andrey Pogorelov
Member

Откуда: Ростов-на-Дону
Сообщений: 312
iap,
Большое спасибо, а немогли бы Вы подсказать случай если нужно, найти разность между узлам и потомками.
4 авг 09, 10:59    [7494150]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Flying Dutchman
Member

Откуда: Arnhem, Голландия
Сообщений: 196
Andrey Pogorelov
Andrey Pogorelov
Привет всем.
Имеется таблица с древовидной структурой
id, par_id, level, sum
1,   0,       1,     800
2,   1,       2,     300  
3,   1,       2,     100
4,   1,       2,     400
5,   2,       3,     100
6,   5,       4,      50
7,   5,       4,      50
8,   4,       3,     200
9,   4,       3,     200

800
   |->300
        |-> 100
              |-> 50
              |-> 50
   |->100
   |->400
        |-> 200
        |-> 200
Необходимо пройтись по веткам дерева и собрать значение sum для каждого родителя.


Задачу можно решить путем написания рекурсивного запроса с использованием CTE. Это подробно описывается, например, в книге Бен-Гана
4 авг 09, 13:15    [7495321]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Flying Dutchman
Задачу можно решить путем написания рекурсивного запроса с использованием CTE. Это подробно описывается, например, в книге Бен-Гана
Надо же! А я бесплатно написал.
Хотя, может, у Бен-Гана по-другому как-нибудь (увы, не читал).
4 авг 09, 13:25    [7495387]     Ответить | Цитировать Сообщить модератору
 Re: Обход дерева  [new]
Andrey Pogorelov
Member

Откуда: Ростов-на-Дону
Сообщений: 312
Други, горю спасайте.
id, par_id, level, summa, opl
1,   0,       1,       900,  
2,   1,       2,       300, 
3,   1,       2,       200,
4,   1,       2,       400,
5,   2,       3,       100,
6,   5,       4,        50,
7,   5,       4,        50,
8,   4,       3,       100,
9,   4,       3,       100,

summa,                    opl
900                        100 
   |->300                 100
        |-> 200           100
              |-> 50       50
              |-> 50       50 
   |->100                 100
   |->400                 200 
        |-> 100           100
        |-> 100           100


opl - должно собираться таким макаром
для 4-го уровня остается как и sum
для 3-го opl = summa - sum(4-го уровня) для данной ветки
для 2-го opl = summa -sum(3-го уровня)
для 1-го opl = summa -sum(2-го уровня)
4 авг 09, 13:41    [7495530]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить