Реализация множественного родительского дерева (или орграфа) SQL Server 2005
Мне нужно реализовать многопартийное дерево (или орграф) на SQL Server 2005. Я прочитал несколько статей, но в большинстве из них используются однопартийные деревья с уникальным корнем, как показано ниже.
-My PC
-Drive C
-Documents and Settings
-Program Files
-Adobe
-Microsoft
-Folder X
-Drive D
-Folder Y
-Folder Z
В этом, все происходит из корневого элемента (мой компьютер).
В моем случае у ребенка может быть более одного родителя, например:
G A
\ /
B
/ \
X C
/ \
D E
\ /
F
Итак, у меня есть следующий код:
create table #ObjectRelations
(
Id varchar(20),
NextId varchar(20)
)
insert into #ObjectRelations values ('G', 'B')
insert into #ObjectRelations values ('A', 'B')
insert into #ObjectRelations values ('B', 'C')
insert into #ObjectRelations values ('B', 'X')
insert into #ObjectRelations values ('C', 'E')
insert into #ObjectRelations values ('C', 'D')
insert into #ObjectRelations values ('E', 'F')
insert into #ObjectRelations values ('D', 'F')
declare @id varchar(20)
set @id = 'A';
WITH Objects (Id, NextId) AS
( -- This is the 'Anchor' or starting point of the recursive query
SELECT rel.Id,
rel.NextId
FROM #ObjectRelations rel
WHERE rel.Id = @id
UNION ALL -- This is the recursive portion of the query
SELECT rel.Id,
rel.NextId
FROM #ObjectRelations rel
INNER JOIN Objects -- Note the reference to CTE table name (Recursive Join)
ON rel.Id = Objects.NextId
)
SELECT o.*
FROM Objects o
drop table #ObjectRelations
Который возвращает следующий набор:
Id NextId
-------------------- --------------------
A B
B C
B X
C E
C D
D F
E F
Ожидаемый результат SET:
Id NextId
-------------------- --------------------
G B
A B
B C
B X
C E
C D
D F
E F
Обратите внимание, что отношение G-> B отсутствует, потому что оно запрашивает начальный объект (который также не работает для меня, потому что я не знаю корневой объект с самого начала), и использование A в качестве начальной точки будет игнорировать отношения G-> B.
Таким образом, этот код не работает в моем случае, потому что он запрашивает начальный объект, что очевидно в SINGLE-родительском дереве (всегда будет корневым объектом). Но в многопользовательском дереве у вас может быть более 1 «корневого» объекта (как в примере, G и A - это «корневые» объекты, где root - это объект, у которого нет родителя (предка)).
Так что я застрял здесь ... Мне нужно изменить запрос, чтобы НЕ запрашивать начальный объект, и рекурсивно пройти по всему дереву. Я не знаю, возможно ли это с реализацией (Id, NextId) ... может быть, мне нужно хранить ее как график, используя какую-то матрицу инцидентности, матрицу смежности или что-то еще (см.http://willets.org/sqlgraphs.html).
Любая помощь? Что вы думаете, ребята? Большое спасибо за ваше время =)
Ура!
Источники:Источник 1 Источник 2 Источник 3