从同一表的父子递归获取最后一条记录

时间:2019-03-26 09:35:20

标签: sql sql-server sql-optimization

我想从同一张表中获取最后一个参考ID。我有下表。

 ID   UserId   DelegatedToUserId
 1      100       101
 2      101       102
 3      102       103
 4      103       NULL
 5      104       109

我只是无法理解。我知道我想要的,只是无法在屏幕上显示出来。因此,当我要求100时,查询应返回103,而当我再次要求101或102时,查询应返回103。当用户输入104时,查询应返回109

当我要求103时,应该返回103,因为没有委托。

这可以在单个sql查询中完成吗?

2 个答案:

答案 0 :(得分:3)

  

这可以在单个sql查询中完成吗?

如果您不知道层次结构可以扩展到什么级别,则需要使用递归CTE。如果只是1或2级,则可以在单个查询中无需递归CTE来完成。

您可以像下面那样使用递归CTE来获得所需的输出。

;WITH mytest 
     AS (SELECT P.userid, 
                P.delegatedtouserid, 
                1 AS LVL 
         FROM   @table P 
         WHERE  userid = 100 
         UNION ALL 
         SELECT P1.userid, 
                P1.delegatedtouserid, 
                M.lvl + 1 AS LVL 
         FROM   @table P1 
                INNER JOIN mytest M 
                        ON M.delegatedtouserid = P1.userid) 

SELECT TOP 1 WITH ties * 
FROM   mytest 
ORDER  BY Row_number() OVER (ORDER BY lvl DESC); 

注意:将@table替换为您的实际表名。

Online Demo

答案 1 :(得分:1)

我个人会这样:

DECLARE @UserID int = 103;

WITH VTE AS
    (SELECT *
     FROM (VALUES (1, 100, 101),
                  (2, 101, 102),
                  (3, 102, 103),
                  (4, 103, NULL),
                  (5, 104, 109)) AS V (ID, UserID, DelegatedToUserID) ),
rCTE AS
    (SELECT V.ID,
            V.UserID,
            V.DelegatedToUserID
     FROM VTE V
     WHERE UserID = @UserID
     UNION ALL
     SELECT V.ID,
            V.UserID,
            V.DelegatedToUserID
     FROM rCTE r
          JOIN VTE V ON r.DelegatedToUserID = V.UserID)
SELECT *
FROM rCTE
WHERE rCTE.DelegatedToUserID IS NULL;

但是,正如我在评论中所提到的,由于表中不存在用户104,传递109将返回没有行