Sql 如何获得递归CTE中生成的最后一条记录?

Sql 如何获得递归CTE中生成的最后一条记录?,sql,sql-server,recursion,common-table-expression,Sql,Sql Server,Recursion,Common Table Expression,在下面的代码中,我使用SQLServer2005中的递归CTE(公共表表达式)来尝试查找基本层次结构的顶级父级。此层次结构的规则是每个CustID都有一个ParentID,如果CustID没有父项,则ParentID=CustID,它是最高级别 DECLARE @LookupID int --Our test value SET @LookupID = 1 WITH cteLevelOne (ParentID, CustID) AS ( SELECT a.ParentID

在下面的代码中,我使用SQLServer2005中的递归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
)
我从上面的代码中得到的结果是:

ParentID    CustID
4            1
5            4
5            5
我想要的只是结果的最后一行:

ParentID    CustID
5            5
如何返回CTE中生成的最后一条记录(即最高级别的CustID)


还要注意,此表中有多个不相关的CustID层次结构,因此我不能仅从tblCustomer中选择*FROM,其中ParentID=CustID。我无法按ParentID或CustID排序,因为ID号与它在层次结构中的位置无关。

我不确定我是否完全理解这个问题,但为了解决这个问题,您可以尝试:

SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC

这假设CustID也像示例中那样有序,而不是GUID。

如果您只是想要最高的递归深度,您不能这样做吗?那么,当您实际查询CTE时,只需查找具有max(深度)的行即可?像这样:

DECLARE @LookupID int

--Our test value
SET @LookupID = 1;

WITH cteLevelOne (ParentID, CustID, Depth) AS
(
        SELECT   a.ParentID, a.CustID, 1
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID, c.Depth + 1
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
        WHERE c.CustID <> a.CustID
)
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone)

我不认为CustomerID一定是您所描述的案例中想要订购的,但我也不完全清楚这个问题。

首先,如果任何父项和子项相同,cte将无法完成。由于它是一个递归CTE,因此必须终止它。如果父级id和客户id相同,循环将不会结束

味精530,16级,状态1,第15行 声明终止了。在语句完成之前,已耗尽最大递归100

DECLARE @LookupID int

--Our test value
SET @LookupID = 1;

WITH cteLevelOne (ParentID, CustID, Depth) AS
(
        SELECT   a.ParentID, a.CustID, 1
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID, c.Depth + 1
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
        WHERE c.CustID <> a.CustID
)
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone)
select top 1 * from CTELevelone order by Depth desc