【问题标题】:Get all parents in parent child hierarchy获取父子层次结构中的所有父级
【发布时间】:2023-03-31 20:12:01
【问题描述】:

我的表中有以下数据

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              

我有以下查询来获取 status=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

【问题讨论】:

  • 你能举一个预期结果与源数据不同的例子吗?

标签: sql sql-server sql-server-2008 common-table-expression


【解决方案1】:
  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

【讨论】:

    【解决方案2】:

    我做了一个递归 CTE - 我从底部开始,任何没有子文件夹的文件夹。从那里,我传递了在“GOOD”列中是否遇到“1”状态,并且 distinct 清除了从底部开始创建的重复项。

    ;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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      • 2016-03-13
      • 2015-07-28
      相关资源
      最近更新 更多