我正在使用Microsoft SQL Server 2008并尝试使用递归查询完成与此帖非常相似的内容:Recursive Child/Parent queries in T/SQL
当然,我试图简化事情;希望我以清晰的方式这样做。我的表看起来像这样:
Parent Child
A A
A B
B D
D H
D I
A C
C E
E C
E J
E K
C F
C G
视觉上关系看起来像这样:
A
B
D
H
I
C
E
C
J
K
F
G
我需要在表中创建一个新列,表示子实体到顶层的路径(在本例中为A):
Parent Child Chain
A A A
A B A,B
B D A,B,D
D H A,B,D,H
D I A,B,D,I
A C A,C
C E A,C,E
E C A,C,E,C
E J A,C,E,J
E K A,C,E,K
C F A,C,F
C G A,C,G
这里的皱纹,以及父子可能不是这里使用的术语的原因可以在实体C中看到,实体C既是父实体也是实体E的子实体,这导致无穷无尽的递归循环。 / p>
我的想法是更新递归循环中的链值,并限制对链列中具有NULL值的实体的递归调用。这个想法是仅在第一次遇到实体时递归实体。我所拥有的将无法工作,我不确定如何将更新集成到递归调用中:
WITH r(parent,child,mychain)
AS
(
SELECT parent, child, child AS myChain
FROM myTable
WHERE parent = 'A' AND
parent <> child AND
chain IS NULL
UNION ALL
SELECT v.parent, v.child, myChain + ',' + v.child AS myChain
FROM myTable v
INNER JOIN r ON r.child = v.parent
WHERE v.parent <> v.child
)
UPDATE myTable
SET chain = r.myChain
FROM myTable AS c
JOIN r ON c.ID = r.ID
关于如何实现这一目标的任何建议?
提前致谢。
修改
可能是我过度简化了一点。因为父列和子列的实际值很长(在20多个字符的邻域中),我真的需要使用记录ID创建一个链,作为值。我修改了Simon的建议,如下所示。这让我非常接近;然而,C - > E记录没有输出(所有记录最终都应该通过链更新)。这可能无关紧要;我还在努力解决这个问题。
with r as
(
SELECT id, parent, child,
CAST( id AS VARCHAR(1024) ) AS CHAIN,
0 as level
FROM myTable
WHERE id = '1'
UNION ALL
SELECT c.id, c.parent, c.child,
cast( (r.CHAIN + ',' + CAST( c.id AS varchar(10)) ) AS varchar(1024)) AS CHAIN,
r.level + 1 as level
FROM myTable c
JOIN r
ON r.child = c.parent
WHERE c.parent != c.child AND r.parent != c.child
)
select * from r order by r.level, r.parent, r.child;
答案 0 :(得分:1)
试试这个:
with r as
(
SELECT parent, child,
CAST( (parent + ',' + child) AS VARCHAR(10)) AS chain,
0 as level
FROM myTable
WHERE parent = 'A'
AND parent != child
UNION ALL
SELECT c.parent, c.child,
cast((r.chain + ',' + c.child) as varchar(10)) AS chain,
r.level + 1 as level
FROM myTable c
JOIN r
ON r.child = c.parent
WHERE r.chain NOT LIKE '%,' + c.child + ',%'
)
select *
from r
order by r.level, r.parent, r.child;
查看:SQL Fiddle