SQL Server - Получить всех детей подряд в отношениях многих ко многим? - PullRequest
2 голосов
/ 02 сентября 2011

Я пытаюсь написать рекурсивный запрос в SQL Server, который в основном перечисляет иерархию «родитель-потомок» от данного родителя. Родитель может иметь несколько детей, и ребенок может принадлежать нескольким родителям, поэтому он хранится в отношении «многие ко многим».

Я изменил следующий запрос из другого, несколько связанного вопроса, однако он не доходит до дерева и выбирает только дочерний элемент первого уровня ...

DECLARE @ObjectId uniqueidentifier
SET @ObjectId = '1A213431-F83D-49E3-B5E2-42AA6EB419F1';

WITH Tree AS
(
   SELECT A.*
   FROM Objects_In_Objects A
   WHERE A.ParentObjectId = @ObjectId

   UNION ALL

   SELECT B.*
   FROM Tree A
   JOIN Objects_In_Objects B
   ON A.ParentObjectId = B.ObjectId
)
SELECT *
FROM Tree
INNER JOIN Objects ar on tree.ObjectId = ar.ObjectId

Кто-нибудь знает, как изменить запрос, чтобы он прошел весь путь по «дереву»? Или это невозможно при использовании вышеуказанной конструкции?

Предметы

Столбцы: ObjectId | Name

Objects_In_Objects

Столбцы: ObjectId | ParentObjectId

Пример данных:

Предметы

ObjectId                             | Name
1A213431-F83D-49E3-B5E2-42AA6EB419F1 | Main container  
63BD908B-54B7-4D62-BE13-B888277B7365 | Sub container  
71526E15-F713-4F03-B707-3F5529D6B25E | Sub container 2  
ADA9A487-7256-46AD-8574-0CE9475315E4 | Object in multiple containers

Объекты в объектах

ObjectId                             | ParentObjectId                    
ADA9A487-7256-46AD-8574-0CE9475315E4 | 71526E15-F713-4F03-B707-3F5529D6B25E
ADA9A487-7256-46AD-8574-0CE9475315E4 | 63BD908B-54B7-4D62-BE13-B888277B7365
63BD908B-54B7-4D62-BE13-B888277B7365 | 1A213431-F83D-49E3-B5E2-42AA6EB419F1
71526E15-F713-4F03-B707-3F5529D6B25E | 1A213431-F83D-49E3-B5E2-42AA6EB419F1

Ответы [ 3 ]

1 голос
/ 02 сентября 2011

Такой рекурсивный CTE (Common Table Expression) будет goo полностью .

Попробуйте это:

;WITH Tree AS
(
   SELECT A.ObjectID, A.ObjectName, o.ParentObjectID, 1 AS 'Level'
   FROM dbo.Objects A
   INNER JOIN dbo.Objects_In_Objects o ON A.ObjectID = o.ParentObjectID
   WHERE A.ObjectId = @ObjectId           -- use the A.ObjectId here

   UNION ALL

   SELECT A2.ObjectID, A2.ObjectName, B.ParentObjectID, t.Level + 1 AS 'Level'
   FROM Tree t 
   INNER JOIN dbo.Objects_In_Objects B ON B.ParentObjectID = t.ObjectID
   INNER JOIN dbo.Objects A2 ON A2.ObjectId = B.ObjectId        
)
SELECT *
FROM Tree
INNER JOIN dbo.Objects ar on tree.ObjectId = ar.ObjectId

Если вы измените это - это работает для вас сейчас? (Я добавил столбец Level - обычно помогает понять «глубину» в иерархии для каждой строки)

Кажется, я получаю правильный вывод на моем экземпляре SQL Server, по крайней мере ...

1 голос
/ 02 сентября 2011
declare @Objects_In_Objects table
(
  ObjectID uniqueidentifier, 
  ParentObjectId uniqueidentifier
)

declare @Objects table
(
  ObjectId uniqueidentifier, 
  Name varchar(50)
)

insert into @Objects values
('1A213431-F83D-49E3-B5E2-42AA6EB419F1', 'Main container'),  
('63BD908B-54B7-4D62-BE13-B888277B7365', 'Sub container'),  
('71526E15-F713-4F03-B707-3F5529D6B25E', 'Sub container 2'),  
('ADA9A487-7256-46AD-8574-0CE9475315E4', 'Object in multiple containers')

insert into @Objects_In_Objects values
('ADA9A487-7256-46AD-8574-0CE9475315E4', '71526E15-F713-4F03-B707-3F5529D6B25E'),
('ADA9A487-7256-46AD-8574-0CE9475315E4', '63BD908B-54B7-4D62-BE13-B888277B7365'),
('63BD908B-54B7-4D62-BE13-B888277B7365', '1A213431-F83D-49E3-B5E2-42AA6EB419F1'),
('71526E15-F713-4F03-B707-3F5529D6B25E', '1A213431-F83D-49E3-B5E2-42AA6EB419F1')


DECLARE @ObjectId uniqueidentifier
SET @ObjectId = '1A213431-F83D-49E3-B5E2-42AA6EB419F1';

WITH Tree AS
(
   SELECT A.ObjectID,
          A.ParentObjectId
   FROM @Objects_In_Objects A
   WHERE A.ParentObjectId = @ObjectId

   UNION ALL

   SELECT B.ObjectID,
          B.ParentObjectId
   FROM Tree A
   JOIN @Objects_In_Objects B
   ON B.ParentObjectId = A.ObjectId
)
SELECT *
FROM Tree
INNER JOIN @Objects ar on tree.ObjectId = ar.ObjectId;

Это то, что вы ищете?http://data.stackexchange.com/stackoverflow/q/111357/

0 голосов
/ 02 сентября 2011
...