Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
30.05.2020, 14:08
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Вопрос для разминки ума умных людей форума)) Классическое дерево. За каждым узлом закреплен небольшой набор данных int, например [52,6] Уровень в таблице присутствует (bal_lev). Корневого элемента в таблице нет, он имеет id = 1 Каким способом можно вычесть листья из своих узлов, начиная с конца дерева, и получившиеся узлы таким же образом повычитать, до самых корневых узлов? Листья при этом остаются, как есть. Т.е. в этом примере нужно: -- из узла 66 вычесть данные узлов 67 и 73, -- из узла 71 вычесть данные узлов 74 и 72, -- из узла 70 вычесть данные узла 71, (версия 2008R2) -- ИСХОДНОЕ ДЕРЕВО, уровней n (поле уровня имеется): 66, 70, 71,... - это просто id узлов элементов [52,6], [30,2],... - это просто данные этих узлов Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
============================ -- ЖЕЛАЕМОЕ ДЕРЕВО: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
============================ -- ИСХОДНАЯ ТАБЛИЦА: DECLARE @Tab_BTree TABLE ( [bal_id] int, [bal_id_parent] int, [bal_lev] int, [b_data1] int, [b_data2] int -- (а возможно и data3, data4,..) ) INSERT INTO @Tab_BTree VALUES (66, 1, 1, 52, 6) INSERT INTO @Tab_BTree VALUES (67, 66, 2, 30, 2) INSERT INTO @Tab_BTree VALUES (73, 66, 2, 20, 4) INSERT INTO @Tab_BTree VALUES (74, 71, 3, 8 , 10) INSERT INTO @Tab_BTree VALUES (72, 71, 3, 2 , 16) INSERT INTO @Tab_BTree VALUES (70, 1, 1, 15, 26) INSERT INTO @Tab_BTree VALUES (71, 70, 2, 14, 26) SELECT * FROM @Tab_BTree Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
================================================== -- ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ SELECT * FROM @Tab_Result Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8.
Если в начальном рекурсивном запросе делать выборку по максимальному уровню, то есть проблема - не все ветви могут быть заполнены до максимального уровня (в этом примере ветвь 70 до 3-го, но, например, ветвь 66 - до 2-го), а значит могут и не попасть в результат. Подскажите, как же это можно сделать? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 14:22
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Наверно не совсем корректно сформулирован вопрос, думаю, что расчет при рекурсии нужно вести не с конца дерева, а с корневых веток. Ну в любом случае, результат должен быть именно такой, как в результирующей табличке. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 15:16
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Есть идеи? ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 15:31
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Mtgktem, ветки, листья, рекурсия... зачем тут это всё? просуммируйте данные с группировкой по bal_id_parent и получите идентификаторы строк для изменения и какие величины должны фигурировать в инструкции UPDATE ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 17:20
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Дмитрий Мух, спасибо! В (нужном мне) простейшем варианте решилось так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
Для моих целей этого вполне достаточно. В моем случае - из предка вычитаются потомки, вычет происходит разово . Но стало понятно, что из этой задачки выходит задачка посложнее. Другая задачка) с другой результирующей табличкой. Ради интереса можно попытаться вычитать узлы, начиная от листьев до корня, накапливая этот вычет по всей ветви. А как такое сделать? Можно с примером? ) В целях повышения, так сказать, собственной эрудиции)) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 17:38
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Mtgktem, можно и с примером, но не сегодня :) выходные ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 17:49
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
вторая задачка Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 19:14
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Mtgktem, Угу, нода 70 не стыкуется между желаемым деревом и желаемым результатом. Я понимаю, как вы можете получить (11,26), но я не понимаю, как можно получить (11,0). Уточняйте на пальцах. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 20:43
|
|||
---|---|---|---|
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 20:48
|
|||
---|---|---|---|
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 20:54
|
|||
---|---|---|---|
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 20:56
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Сейчас поясню. С первой задачей все ок. Она решена. Сейчас речь идет о второй задачке. Исходное дерево и табличка к ней все те же. Поясняю на пальцах про желаемое дерево и желаемую табличку для второй задачки: с веткой 66 получается все так же, как и в первой. (но если вдруг будет использована рекурсия от листьев к основанию, начиная со всех узлов уровня 3, то важно не потерять эту ветку в расчетах, т.к. листья у ветки 66 начинаются с уровня 2) теперь про ветку 70 (в исходном дереве) -- из предка 71[14,26] вычитаются данные его потомков 74[8,10] и 72[2,16], получается 71[4,0] -- из предка 70[15,26] вычитаются расчитанные данные его потомка 71[4,0], получается 70[11,26] Да, Вы правы, это моя ошибка. Исправляюсь. Правильный желаемый результат для узла 70[11,26] в итоге желаемая табличка должна получиться так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Вкратце - в первой задачке одноразовое вычисление, а в этой задачке дожны учитываться и предыдущие вычтенные данные узла. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
30.05.2020, 21:08
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Дмитрий Мух, Ennor Tiegael, aleks222 Заранее всех благодарю. Всех читаю, пробую, проверяю. Спасибо! ... |
|||
:
Нравится:
Не нравится:
|
|||
|
31.05.2020, 07:41
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Mtgktem, Я так и подумал. Тогда легко, можно даже без циклов: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46.
Учтите только, что если ваше дерево большое и, эээ, раскидистое, то этот код может проигрывать итеративному. Тогда можно попробовать CTE материализовать во временную таблицу и соотв-но проиндексировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
31.05.2020, 11:32
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Спасибо, отлично подходит. А как думаете, примерно со скольки узлов/веток/листьев стоит индексировать? (выявлять путем сравнительных котёнковых экспериментов?) ... |
|||
:
Нравится:
Не нравится:
|
|||
|
31.05.2020, 11:52
|
|||
---|---|---|---|
|
|||
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Mtgktem, Все зависит от ваших реалий. Хорошо проиндексированная исходная таблица на мощном сервере даже и на миллионе записей может показать приемлемую производительность (опять-таки, смотря что для вас "приемлемо"). Сначала попробуйте, как есть. Если слишком медленно, то материализуйте CTE с кластерным индексом по RootId (уникальным его правда сделать не получится, ключ тут, похоже, Id + RelativeNestLevel). К тому же, некоторые столбцы в CTE похоже лишние, ParentId например - можно его выкинуть и немного сэкономить. NestLevel используется только для вычисления RelativeNestLevel и далее не нужен - в случае кэширования во времянку его можно не вставлять в таблицу. Экспериментируйте, в общем. ... |
|||
:
Нравится:
Не нравится:
|
|||
|
31.05.2020, 12:31
|
|||
---|---|---|---|
Дерево. Подскажите, как вычесть из веток все их листья и до самого корня? |
|||
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
Код: sql 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
|
|
start [/forum/topic.php?fid=46&tablet=1&tid=1686052]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
6ms |
check topic access: |
6ms |
track hit: |
87ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
62ms |
get tp. blocked users: |
1ms |
others: | 31ms |
total: | 225ms |
0 / 0 |