1

我有以下递归函数:

ALTER FUNCTION [dbo].[ListAncestors] 
(   
    @Id int
)   
RETURNS TABLE  
As  
RETURN  
(   
    WITH cte As  
    (   
        SELECT
            UserId,
            ManagerId,  
            Forename,
            Surname  
        FROM  
            dbo.Users   
        WHERE  
            UserId = @Id   

        UNION ALL  

        SELECT  
            T.UserID,
            T.ManagerID,  
            T.Forename,   
            T.Surname  
        FROM  
            cte As C INNER JOIN dbo.Users As T   
            ON C.UserID = T.ManagerID   
    )   
    SELECT
        Forename,
   Surname 
    FROM  
        cte
);

基本上它的作用是返回指定用户以下的所有用户的名称(基于他们的 ID)。我想做的是修改这个函数并创建另一个函数来检查一个特定的用户ID是否是另一个的祖先。

我想签名看起来像:

CREATE FUNCTION IsAncestor(@Id int, @AncestorId int) RETURNS BIT
4

2 回答 2

1

如果我们接受初始 CTE 采用一个 ID 并列出该 ID 的所有“祖先”,我认为以下查询会测试这种关系。

WITH cte As  
(   
    SELECT
        UserId,
        Forename,
        Surname  
    FROM  
        dbo.Users   
    WHERE  
        UserId = @Id   

    UNION ALL  

    SELECT  
        T.UserID,  
        T.Forename,   
        T.Surname  
    FROM  
        cte As C INNER JOIN dbo.Users As T   
        ON C.UserID = T.ManagerID and C.UserID <> @ancestorID
)   
SELECT CAST (COUNT(*) as BIT) FROM cte WHERE UserID = @ancestorID

不过这有点奇怪,因为考虑到初始功能,一个人与自己处于“祖先”关系。

顺便说一句,我从 CTE 中的选择语句中删除了 ManagerID,因为它不是必需的

于 2010-08-01T12:15:21.157 回答
1

怎么样:

WHILE @Id IS NOT NULL AND @Id <> @AncestorId
BEGIN
 SET @Id = (
  SELECT ManagerId FROM dbo.Users WHERE UserId = @Id
 )
END

RETURN CASE WHEN @Id IS NOT NULL THEN 1 ELSE 0 END
于 2010-08-01T11:01:04.353 回答