1

考慮以下數據庫表。它由3列組成:IdParentId啓用有條件遞歸SQL選擇

Table

我想產生設置類似如下的結果。基本上對於每個記錄有家長ID,我想要顯示一個額外的列啓用父Id。此列基本上需要遞歸檢查密鑰的層次結構,並在找到Enabled = True的密鑰時停止。

Result

謹以此實現這一上的蒼蠅,而不需要在表中添加任何額外的計算列。

也許這可以通過使用CTE來實現。

+0

#2是不是「寫我的代碼爲我」之類的服務,你應該清楚地認識到這裏經過近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