gpt4 book ai didi

TSQL CTE : How to avoid circular traversal?

转载 作者:行者123 更新时间:2023-12-04 01:32:38 27 4
gpt4 key购买 nike

我编写了一个非常简单的 CTE 表达式,用于检索用户所属的所有组的列表。

规则是这样的,一个用户可以在多个组中,组可以嵌套,这样一个组可以成为另一个组的成员,而且组可以相互成为另一个组的成员,所以组A是组的成员B组和B组也是A组的成员。

我的 CTE 是这样的,显然它会产生无限递归:

            ;WITH GetMembershipInfo(entityId) AS( -- entity can be a user or group
SELECT k.ID as entityId FROM entities k WHERE k.id = @userId
UNION ALL
SELECT k.id FROM entities k
JOIN Xrelationships kc on kc.entityId = k.entityId
JOIN GetMembershipInfo m on m.entityId = kc.ChildID
)

我找不到一个简单的解决方案来回溯我已经录制的那些组。

我想在 CTE 中使用一个额外的 varchar 参数来记录我访问过的所有组的列表,但是使用 varchar 太粗糙了,不是吗?

有更好的方法吗?

最佳答案

您需要在递归中累积一个哨兵字符串。在下面的例子中,我有一个从 A、B、C、D 到 A 的循环关系,然后我避免了一个带有标记字符串的循环:

DECLARE @MyTable TABLE(Parent CHAR(1), Child CHAR(1));

INSERT @MyTable VALUES('A', 'B');
INSERT @MyTable VALUES('B', 'C');
INSERT @MyTable VALUES('C', 'D');
INSERT @MyTable VALUES('D', 'A');

; WITH CTE (Parent, Child, Sentinel) AS (
SELECT Parent, Child, Sentinel = CAST(Parent AS VARCHAR(MAX))
FROM @MyTable
WHERE Parent = 'A'
UNION ALL
SELECT CTE.Child, t.Child, Sentinel + '|' + CTE.Child
FROM CTE
JOIN @MyTable t ON t.Parent = CTE.Child
WHERE CHARINDEX(CTE.Child,Sentinel)=0
)
SELECT * FROM CTE;

结果:
Parent Child Sentinel
------ ----- --------
A B A
B C A|B
C D A|B|C
D A A|B|C|D

关于TSQL CTE : How to avoid circular traversal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11041797/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com