如何获得递归CTE中生成的最后一条记录?
时间:2020-03-05 18:45:14 来源:igfitidea点击:
在下面的代码中,我在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号与它在层次结构中的位置无关。
解决方案
回答
我不确定我是否完全理解该问题,但是可以尝试一下:
SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC
假定CustID也与示例中的顺序相同,而不是像GUID这样的顺序。
回答
如果我们只想获得最高的递归深度,就不能这样做吗?那么,当我们实际查询CTE时,只需查找具有max(Depth)的行?像这样:
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)
或者,根据trevor的建议,可以将其与相同的CTE一起使用:
select top 1 * from CTELevelone order by Depth desc
我认为,在描述的情况下,CustomerID不一定是我们想要订购的东西,但是我也不十分清楚这个问题。