Мне нужно реализовать многопартийное дерево (или орграф) на SQL Server 2005. Я прочитал несколько статей, но большинство из них использует однопользовательские деревья с уникальным корнем, как и следующий.
-My PC
   -Drive C
      -Documents and Settings
      -Program Files
         -Adobe
         -Microsoft
      -Folder X
   -Drive D
      -Folder Y
      -Folder Z
В этом все происходит от корневого элемента (My PC).
В моем случае у ребенка может быть более одного родителя, например:
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
Что возвращает следующий SET:
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-parent (всегда будет корневым объектом). Но в многопользовательском дереве у вас может быть более 1 "корневой" объект (например, в G, а A - "корневые" объекты, где root - это объект, у которого нет родителя (предка)).
Итак, я как бы застрял здесь... Мне нужно изменить запрос, чтобы НЕ запрашивать начальный объект и рекурсивно пересекать все дерево. Я не знаю, возможно ли это с реализацией (Id, NextId)... Может быть, мне нужно сохранить его, как граф, используя какую-либо матрицу инцидентов, матрицу смежности или что-то еще (см. http://willets.org/sqlgraphs.html).
Любая помощь? Что вы думаете, ребята? Большое спасибо за ваше время =)
Ура!
Источники: Источник 1 Источник 2 Источник 3
