从同一个 table 父子递归获取最后一条记录
Recursively get last record from same table parent child
我想从同一个 table 中获取最后一个参考 ID。我关注 table.
ID UserId DelegatedToUserId
1 100 101
2 101 102
3 102 103
4 103 NULL
5 104 109
我只是无法理解。我知道我想要什么,只是无法在屏幕上显示出来。因此,当我要求 100 查询时,应该 return 103,当我再次询问 101 或 102 时,它应该 return 103。当用户输入 104 时,它应该 return 109
当我要求 103 时,它应该 return 103,因为没有代表。
这可以在单个 sql 查询中完成吗?
can this be done in single sql query ?
如果您不知道层次结构可以达到什么级别,则需要使用递归 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
替换为您的实际table姓名。
就我个人而言,我会这样做:
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
将 return 没有行 因为用户 109
不存在于table.
我想从同一个 table 中获取最后一个参考 ID。我关注 table.
ID UserId DelegatedToUserId
1 100 101
2 101 102
3 102 103
4 103 NULL
5 104 109
我只是无法理解。我知道我想要什么,只是无法在屏幕上显示出来。因此,当我要求 100 查询时,应该 return 103,当我再次询问 101 或 102 时,它应该 return 103。当用户输入 104 时,它应该 return 109
当我要求 103 时,它应该 return 103,因为没有代表。
这可以在单个 sql 查询中完成吗?
can this be done in single sql query ?
如果您不知道层次结构可以达到什么级别,则需要使用递归 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
替换为您的实际table姓名。
就我个人而言,我会这样做:
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
将 return 没有行 因为用户 109
不存在于table.