Это для SQL Server 2012. Мне нужно создать набор данных, содержащий ссылки, и все ссылки ссылок из заданного начального ParentId с учетом следующей таблицы
CREATE TABLE Relations (
Id INT NOT NULL PRIMARY KEY,
ParentId INT NOT NULL,
ChildId INT
);
Итак, для следующего набора данных:
1 A B
2 B C
3 C D
4 F D
5 F G
6 X Y
7 Y Z
Начиная с C, я ожидал получить строки с 1 по 5, поскольку все они связаны с C через родительские или дочерние иерархии. Например. G имеет родителя F, который является родителем D, который является дочерним элементом C.
Это не стандартный запрос иерархии, поскольку реального корня нет, и мне нужно получить ссылки в обоих направлениях. Итак, это означает, что я не могу использовать трюк с рекурсией CTE. вот моя попытка:
--Hierarchical Query using Common Table Expressions
WITH ReportingTree (Id, Parent, Child, Lvl)
AS
(
--Anchor Member
SELECT Id,
ParentId,
ChildId,
0 as Lvl
FROM Relations WHERE ParentId = 9488
UNION ALL
--Recusive Member
SELECT
cl.Id,
cl.ParentId,
cl.ChildId,
r1.Lvl+1
FROM [dbo].[CompanyLinks] cl
INNER JOIN ReportingTree r1 ON ReportingTree.Parent = cl.Child
INNER JOIN ReportingTree r2 ON cl.FromCompanyId = r2.Parent <-- errors
)
SELECT * FROM ReportingTree
Моя вторая попытка включала временную таблицу и цикл while. Это работает, но оказывается очень медленным:
BEGIN
CREATE TABLE #R (
Id INT NOT NULL PRIMARY KEY NONCLUSTERED,
ParentId INT NOT NULL,
ChildId INT
);
CREATE CLUSTERED INDEX IX_Parent ON #R (ParentId);
CREATE INDEX IX_Child ON #R (ChildId);
INSERT INTO #R
SELECT Id,ParentId ChildId
FROM Relations
WHERE ParentId = 9488 OR ChildId = 9488;
WHILE @@RowCount > 0
BEGIN
INSERT INTO #R
SELECT cl.Id,cl.ParentId, cl.ChildId
FROM #R INNER JOIN
Relations AS cl ON cl.ChildId = #R.ChildId OR cl.ParentId = #R.ParentId OR cl.ChildId = #R.Parent OR cl.ParentId = #R.Child
EXCEPT
SELECT Id,ParentId, ChildId
FROM #R;
END
SELECT * FROM Relations cl inner Join #Relations r ON cl.Id = #R.Id
DROP TABLE #R
КОНЕЦ
Может ли кто-нибудь предложить работоспособное решение для этого?
D
, может иметь несколько родителей, напримерC
иF
. - person Giorgos Betsos   schedule 28.08.2015D
является потомкомC
, поэтому для достиженияD
нам нужно спуститься вниз по иерархии. Но тогда мы должны подняться, чтобы достичьF
, а затем снова спуститься, чтобы достичьG
. - person Giorgos Betsos   schedule 28.08.2015