2014-04-01 60 views
0

,我有以下數據在我的表獲取所有的父母在父子層次

ID   NAME       PARENTID STATUS 
----------- ------------------------------ ----------- ------ 
1   Folder A      0   0 
2   Folder B      1   0 
3   Folder C      2   1 
4   Folder D      1   0 
5   Folder E      4   0 
6   Folder G      5   0 
7   Folder H      6   1 

上面記載是從表[@temp。

[Name] - Folder Name 
[ID] - Unique ID of folder in database (identity) 
[ParentID] - Represents the parent of current folder. 

查詢表中所填寫上面的數據:

DECLARE @Temp TABLE 
    (
     [ID] INT IDENTITY(1, 1) , 
     [NAME] VARCHAR(30) , 
     [PARENTID] INT, 
     [STATUS] BIT 
    ) 

    INSERT INTO @Temp 
      SELECT 'Folder A' , 
        0, 0 
      UNION 
      SELECT 'Folder B' , 
        1, 0 
      UNION 
      SELECT 'Folder C' , 
        2, 1 
      UNION 
      SELECT 'Folder D' , 
        1, 0 
      UNION 
      SELECT 'Folder E' , 
        4, 0 
      UNION 
      SELECT 'Folder G' , 
        5, 0 
      UNION 
      SELECT 'Folder H' , 
        6, 1    

我有以下查詢來獲取記錄,其中狀態= 1

SELECT * 
    FROM  @Temp WHERE [STATUS]=1  

這給下面的輸出

ID   NAME       PARENTID STATUS 
----------- ------------------------------ ----------- ------ 
3   Folder C      2   1 
7   Folder H      6   1 

我的目標是獲取那些記錄,這些記錄是父代(直到parentid = 0)的記錄隨同上述查詢。即我想這個輸出包含文件夾C和文件夾H的父母:

ID   NAME       PARENTID STATUS 
----------- ------------------------------ ----------- ------ 
1   Folder A      0   0 
2   Folder B      1   0 
3   Folder C      2   1 
4   Folder D      1   0 
5   Folder E      4   0 
6   Folder G      5   0 
7   Folder H      6   1 
+0

您能給出一個預期結果的例子,其中預期結果與源數據不一樣嗎? –

回答

0
DECLARE @Temp TABLE 
    (
     [ID] INT IDENTITY(1, 1) , 
     [NAME] VARCHAR(30) , 
     [PARENTID] INT , 
     [STATUS] BIT 
    ) 

    INSERT INTO @Temp 
      SELECT 'Folder A' , 
        0 , 
        0 
      UNION 
      SELECT 'Folder B' , 
        1 , 
        0 
      UNION 
      SELECT 'Folder C' , 
        2 , 
        1 
      UNION 
      SELECT 'Folder D' , 
        1 , 
        0 
      UNION 
      SELECT 'Folder E' , 
        4 , 
        0 
      UNION 
      SELECT 'Folder G' , 
        5 , 
        1 
      UNION 
      SELECT 'Folder H' , 
        6 , 
        0      


    CREATE TABLE #TempTable 
    (
     [RowIndex] INT IDENTITY(1, 1) , 
     [ID] INT , 
     [ParentID] INT 
    ) 
    DECLARE @TempIds TABLE ([ID] INT)    
    INSERT INTO #TempTable 
      ([ID] , 
       [ParentID] 
      ) 
      SELECT [ID] , 
        [ParentID] 
      FROM @Temp 
      WHERE [STATUS] = 1 



    DECLARE @intFlag INT 
    DECLARE @Count INT 
    SET @intFlag = 1 
    SELECT @Count = COUNT(1) 
    FROM  @Temp 
    WHILE (@intFlag <= @Count) 
    BEGIN 
     PRINT @intFlag 

     DECLARE @ID INT 
     SELECT @ID = [ParentID] 
     FROM #TempTable 
     WHERE RowIndex = @intFlag 
     SET @intFlag = @intFlag + 1; 
     WITH CTE 
        AS (SELECT ID , 
           ParentID 
         FROM  @Temp 
         WHERE ID = @ID 
         UNION ALL 
         SELECT MainTbl.ID , 
           MainTbl.ParentID 
         FROM  @Temp MainTbl 
           INNER JOIN cte ON MainTbl.ID = cte.ParentID 
        ) 
      INSERT INTO @TempIds 
        SELECT ID 
        FROM CTE 


    END 



    ;WITH cte 
      AS (SELECT DISTINCT 
         ID 
       FROM  @TempIds 
      ) 
    SELECT T.* 
    FROM cte 
      INNER JOIN @Temp T ON [T].ID = cte.ID 
    UNION 
    SELECT T1.* 
    FROM #TempTable TempTable 
      INNER JOIN @Temp T1 ON [TempTable].ID = T1.ID 

    DROP TABLE #TempTable 

輸出:

ID   NAME       PARENTID STATUS 
----------- ------------------------------ ----------- ------ 
1   Folder A      0   0 
2   Folder B      1   0 
3   Folder C      2   1 
4   Folder D      1   0 
5   Folder E      4   0 
6   Folder G      5   1 
0

我做了一個遞歸CTE - 我開始與底部,任何沒有孩子的文件夾。從那裏,我傳遞了在'GOOD'列中是否遇到'1'狀態,並且清除了從底部開始創建的重複項。

;WITH CTE AS 
(
    SELECT ID, NAME, PARENTID, STATUS GOOD, STATUS 
    FROM @Temp T1 
    WHERE NOT EXISTS (SELECT * FROM @Temp T2 WHERE T2.PARENTID = T1.ID) 

    UNION ALL 

    SELECT T.ID, T.NAME, T.PARENTID, T.STATUS | C.GOOD GOOD, T.STATUS 
    FROM @Temp T 
    JOIN CTE C 
    ON C.PARENTID = T.ID 
) 

SELECT DISTINCT ID, NAME, PARENTID, STATUS FROM CTE 
WHERE GOOD = 1 
ORDER BY ID ASC