如何获取递归 CTE 中生成的最后一条记录?
在下面的代码中,我使用 SQL Server 2005 中的递归 CTE(公用表表达式)来尝试查找基本层次结构的顶级父级。 此层次结构的规则是每个 CustID 都有一个 ParentID,如果 CustID 没有父级,则 ParentID = CustID 并且它是最高级别。
DECLARE @LookupID int
--Our test value
SET @LookupID = 1
WITH cteLevelOne (ParentID, CustID) AS
(
SELECT a.ParentID, a.CustID
FROM tblCustomer AS a
WHERE a.CustID = @LookupID
UNION ALL
SELECT a.ParentID, a.CustID
FROM tblCustomer AS a
INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID
WHERE c.CustID <> a.CustomerID
)
因此,如果 tblCustomer 看起来像这样:
ParentID CustID
5 5
1 8
5 4
4 1
我从上面的代码得到的结果是:
ParentID CustID
4 1
5 4
5 5
我想要的只是该结果的最后一行:
ParentID CustID
5 5
如何返回 CTE 中生成的最后一条记录(这将是最高级别的 CustID)?
另请注意,此表中有多个不相关的 CustID 层次结构,因此我不能只执行 SELECT * FROM tblCustomer WHERE ParentID = CustID。 我无法按 ParentID 或 CustID 进行排序,因为 ID 号与其在层次结构中的位置无关。
In the code below I am using a recursive CTE(Common Table Expression) in SQL Server 2005 to try and find the top level parent of a basic hierarchical structure. The rule of this hierarchy is that every CustID has a ParentID and if the CustID has no parent then the ParentID = CustID and it is the highest level.
DECLARE @LookupID int
--Our test value
SET @LookupID = 1
WITH cteLevelOne (ParentID, CustID) AS
(
SELECT a.ParentID, a.CustID
FROM tblCustomer AS a
WHERE a.CustID = @LookupID
UNION ALL
SELECT a.ParentID, a.CustID
FROM tblCustomer AS a
INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID
WHERE c.CustID <> a.CustomerID
)
So if tblCustomer looks like this:
ParentID CustID
5 5
1 8
5 4
4 1
The result I get from the code above is:
ParentID CustID
4 1
5 4
5 5
What I want is just the last row of that result:
ParentID CustID
5 5
How do I just return the last record generated in the CTE (which would be highest level CustID)?
Also note that there are multiple unrelated CustID hierarchies in this table so I can't just do a SELECT * FROM tblCustomer WHERE ParentID = CustID. I can't order by ParentID or CustID because the ID number is not related to where it is in the hierarchy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
首先,如果任何父子相同,则 cte 将不会完成。 由于它是递归 CTE,因此必须终止。 如果 Parent 和 cust id 相同,循环将不会结束。
消息 530,第 16 级,状态 1,第 15 行
声明终止。 在语句完成之前,最大递归次数 100 已用完。
First the cte will not be finished if any of the parent child are same. As it is a recursive CTE it has to be terminated. Having Parent and cust id same , the loop will not end.
Msg 530, Level 16, State 1, Line 15
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
如果您只想获得最高的递归深度,您不能这样做吗?然后,当您实际查询 CTE 时,只需查找具有 max(Depth) 的行? 像这样:
或者,适应特雷弗的建议,这可以与相同的 CTE 一起使用:
我认为 CustomerID 不一定是您所描述的情况下想要订购的内容,但我对这个问题也不是很清楚。
If you just want want the highest recursion depth couldn't you do something like this?Then, when you actually query the CTE just look for the row with max(Depth)? Like so:
or, adapting what trevor suggests, this could be used with the same CTE:
I don't think CustomerID was necessarily what you wanted to order by in the case you described, but I wasn't perfectly clear on the question either.
我不确定我完全理解这个问题,但只是为了 hack & 您可以尝试使用斜杠:
这假设 CustID 也按示例中的顺序排列,而不是类似 GUID 的内容。
I'm not certain I fully understand the problem, but just to hack & slash at it you could try:
That assumes that the CustID is also in order as in the example, and not something like a GUID.