Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Возможно проблема была ранее обсуждена на форуме, - тогда спасибо за ссылку, но в любом случае не могу решить следущую задачу: Имеем таблицу, описывающюю дерево подразделений предприятия : ID, PARENT_ID, LEV - собственно id, ссылка на родитель-подразделение на уровень выше, уровень вложенности подразделения в дереве. Необходимо по заданному id выдать набор этих самых id всех входящих в заданное подразделение подразделений. Поля: ID,PARENT_ID,LEV 1 NULL 1 - Предприятие 2 1 2 - Цех 1 3 1 2 - Цех 2 4 2 3 - Отдел Цеха 1 5 3 3 - Отдел Цеха 2 6 5 4 - Подотдел Отдела Цеха 2 т.о. задав id = 1 должны получить список id 1,2,3,4,5 задав id = 3 -> 3,5,6 Заранее благодарен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 04:18 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Я для работы с деревом использую три поля: id, parent_id и way, где way строка и в ней хранится вся ветка вложенности (по id через разделитель) до текущей позиции, например '0|1|5|130|135'. Если нужно вытащить всю вложенность начиная с текущей позиции (например с 5) то: select id from table where way like '0|1|5'+'%' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 05:39 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Я для работы с деревом использую три поля: id, parent_id и way, где way строка и в ней хранится вся ветка вложенности (по id через разделитель) до текущей позиции, например '0|1|5|130|135'. Если нужно вытащить всю вложенность начиная с текущей позиции (например с 5) то: select id from table where way like '0|1|5'+'%' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 05:41 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Если проектирование начинается с нуля, полезно разобраться со статьей Иерархические структуры, не требующие сопровождения ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 07:02 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Можно написать хранимку, которая будет выбирать все поддерово, обрабатывая его по слоям. Делать это придлется через врем. таблицы. Вот пример CREATE PROCEDURE sp_get_child_department @department_id int, @table_name varchar(12 --Вычислить список подразделений дочерних по отношению к подразделению с кодом @department_id. --Список сохраняется в предварительно созданной таблице с именем @table_name формата (dep_id INT). AS begin declare @rc int, @SQLText NVARCHAR(1000) create table #final ([id] int) create table #tmp1 ([id] int) create table #tmp2 ([id] int) insert into #tmp1 ([id]) values(@department_id) insert into #final ([id]) values(@department_id) set @rc = 1 while @rc != 0 begin truncate table #tmp2 insert into #tmp2 ([id]) select department.department_id from department join #tmp1 on department.department_pred_id = #tmp1.[id] select @rc = @@rowcount if @rc != 0 begin insert into #final ([id]) select #tmp2.[id] from #tmp2 truncate table #tmp1 insert into #tmp1 ([id]) select department.[department_id] from department join #tmp2 on department.department_pred_id = #tmp2.[id] select @rc = @@rowcount if @rc != 0 insert into #final ([id]) select #tmp1.[id] from #tmp1 end end declare @sqltext nvarchar(1000) SET @sqltext = 'INSERT INTO '+@table_name+'(dep_id) (SELECT #final.id FROM department JOIN #final ON department.department_id = #final.[id])' EXEC sp_executesql @sqltext end ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 10:44 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Вообще-то, способов хранения древовидной структуры достаточно много. Еще один пример способа хранения можно посмотреть здесь: http://www.sdm.viptop.ru/articles/sqltrees.html А по поводу собственно вопроса: DECLARE @IDRoot Int, @AllChild VarChar(100) SET @IDRoot = 1 -- значение ID корня, для которого ищем всех потомков SET @AllChild=CONVERT(VarChar(10),@IDRoot) -- найденный список всех потомков SELECT ID, LEV INTO #tabTmp FROM TabTree WHERE Parent_ID=@IDRoot WHILE (SELECT count(*) FROM #TabTmp)>0 BEGIN SELECT TOP 1 @IDRoot=ID FROM #tabTmp ORDER BY LEV -- выделяю первую запись из таблицы #TabTmp DELETE FROM #tabTmp WHERE ID=@IDRoot -- Удаляю уже не нужную первую запись -- Добавляю в таблицу #TabTmp всех потомков для только что удаленной записи INSERT INTO #tabTmp (ID,LEV) SELECT ID,LEV FROM TabTree WHERE Parent_ID=@IDRoot SET @AllChild=@AllChild+','+CONVERT(VarChar(10),@IDRoot) -- Пополняю выходное значение END select @AllChild Список будет упорядочен по возрастанию уровня вложенности (LEV) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 11:08 |
|
||
|
Деревянные списки
|
|||
|---|---|---|---|
|
#18+
Предлагаю создать еще одну таблицу Таблица должна содержать два поля ID и ID_parent Для каждого "родительского" подразделения в этой таблице должно быть столько записей, сколько "детей" у него всего есть. Конкретно для вашего примера эта таблица (назовем ее tree) должна содержать следующие данные id id_parent 1 1 2 2 3 3 4 4 5 5 6 6 2 1 3 1 4 1 5 1 6 1 4 2 5 3 6 3 6 5 запросы select id from tree where id_parent = 1 select id from tree where id_parent = 3 возвращают искомую последовательность Плюсы такого подхода - можно без проблем искать как "вверх по дереву" так и "вниз по дереву" с любого уровня. - Хорошее быстродействие. Заполнение таблицы tree происходит при заполнении таблицы подразделений (в этом случае алгоритм наиболее простой). Хотя, конечно, неплохо иметь под рукой процедуру, которая выполняет полный обход дерева и перестраивает данные в таблице tree... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.04.2002, 11:17 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32028284&tid=1823017]: |
0ms |
get settings: |
12ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
147ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
65ms |
get tp. blocked users: |
1ms |
| others: | 231ms |
| total: | 494ms |

| 0 / 0 |
