条件递归SQL选择

条件递归SQL选择,sql,sql-server,recursion,common-table-expression,recursive-query,Sql,Sql Server,Recursion,Common Table Expression,Recursive Query,考虑以下数据库表。它由3列组成:Id、ParentId、Enabled 我希望生成一个类似于以下内容的结果集。基本上,对于每个具有父ID的记录,我想显示一个额外的列启用的父ID。此列基本上需要递归地检查键的层次结构,并在找到已启用=True的键时停止 我希望这可以在运行中实现,而不需要在表中添加任何额外的计算列 也许可以使用CTE尝试以下CTE查询: WITH T1 as (SELECT id, parentId, NULL as EnabledParent

考虑以下数据库表。它由3列组成:Id、ParentId、Enabled

我希望生成一个类似于以下内容的结果集。基本上,对于每个具有父ID的记录,我想显示一个额外的列启用的父ID。此列基本上需要递归地检查键的层次结构,并在找到已启用=True的键时停止

我希望这可以在运行中实现,而不需要在表中添加任何额外的计算列

也许可以使用CTE

尝试以下CTE查询:

WITH T1 as 
(SELECT id,
        parentId,
        NULL as EnabledParentId, 
        ParentID as NextParent 
        FROM T
        WHERE ParentID is not null
UNION ALL
SELECT T1.id, 
       T1.parentId, 
       CASE WHEN T.enabled = 1 
            THEN T.ID 
            ELSE NULL END 
              as EnabledParentId,
       T.ParentID as NextParent
 FROM T1 
 JOIN T ON T1.NextParent = T.Id
 WHERE (nextParent is not Null) and (EnabledParentId IS NULL)
)
SELECT ID,
       ParentID,
       EnabledParentID 
       FROM T1 
       WHERE EnabledParentId IS NOT NULL 
             OR NextParent IS NULL
       ORDER BY ID;

Stackoverflow不是一种“为我编写代码”的服务,在这里呆了近4年后,您应该很清楚这一点。“请表现出你的努力。”佐哈佩尔说得对,但我被困在这里。我一直试图为这个问题创建一个CTE,但似乎无法让它工作。@a_horse_,没有名字MsSQL
DECLARE @myTable TABLE
(
    Id INT NOT NULL,
    ParentId INT NOT NULL,
    EnabledParentId INT
)

DECLARE myCursor CURSOR FOR
SELECT Id
FROM T
WHERE ParentId IS NOT NULL
ORDER BY Id;

OPEN myCursor;

DECLARE @currentId INT;

FETCH NEXT FROM myCursor INTO @currentId;

WHILE @@FETCH_STATUS = 0
BEGIN

    DECLARE @Exists BIT = 0;

    DECLARE @ParentId INT               
    SELECT @ParentId = ParentId
    FROM T
    WHERE Id = @currentId

    WHILE (@ParentId IS NOT NULL AND @Exists = 0)
    BEGIN                   

        IF EXISTS(SELECT * FROM T WHERE Id = @ParentId AND IsEnabled = 1)
        BEGIN

            SET @Exists = 1             

        END
        ELSE
        BEGIN

                SELECT @ParentId = ParentId
                FROM T
                WHERE Id = @ParentId

        END

        IF (@Exists = 1 OR @ParentId IS NULL)
        BEGIN
            INSERT INTO @myTable
            SELECT Id, ParentId, @ParentId
            FROM T
            WHERE Id = @currentId       
        END



    END

   FETCH NEXT FROM myCursor INTO @currentId;
END

CLOSE myCursor;
DEALLOCATE myCursor;

SELECT *
FROM @myTable
ORDER BY 1