1

次のデータベーステーブルを検討してください。それは3つの列で構成されています:Id,親ID,有効です。条件付き再帰SQL選択

Table

私は次のような結果セットを生成したいと思います。基本的に親IDを持つレコードごとに、追加の列が有効になります。親ID。この列は基本的にキーの階層を再帰的にチェックする必要があり、Enabled = Trueというキーが見つかると停止します。

Result

私は、これは、テーブル内の任意の追加の計算カラムを追加する必要なく、その場でこれを実現したいと思います。

おそらく、CTEを使用してこれを達成できます。

+0

StackOverflowのサービス、あなたはここで後にはほぼ4年をよく知っておく必要があり、何かの「私のための私のコードを書く」ようなものではありません。あなたの努力を示してください。 –

+0

@ZoharPeledあなたは正しいですが、私はここにこだわっています。私はこの問題のCTEを作成しようとしてきましたが、それを稼働させることはできません。 – JEPAAB

+0

@a_horse_with_no_name MsSQL – JEPAAB

答えて

1

この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; 
0
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