SQL Server CTE -Find top parentID forEach childID?

后端 未结 9 1074
Happy的楠姐
Happy的楠姐 2020-12-08 08:24

I have a table which contains hierarchy data - something like:

childID  |  parentID
____________________
  1      |     5
  5      |     9
  9      |     20         


        
相关标签:
9条回答
  • 2020-12-08 08:46
    select distinct 
           a.ChildID,a.ParentID,
           --isnull(nullif(c.parentID,b.parentID),a.parentID) as toppa,
           B.parentID
           --,c.parentID
          ,isnull(nullif(d.parentID,a.parentID),c.parentID) as toppa1,a.name
    from myTable a
       inner join myTable c
           on a.parentID=c.parentID
       inner join myTable b
           on b.childID=a.parentID
       inner join myTable d
           on d.childID=b.parentID  
    

    I have using the without CTE expression and then using joins to get the step to step parent for child and then more important Common table expressions were introduced in SQL Server 2005 not in server 2000 so using joins to get values this is basic way for to get parentid for a child value

    0 讨论(0)
  • 2020-12-08 08:49

    select dbo.[fn_getIMCatPath](8)
    select Cat_id,Cat_name,dbo.[fn_getIMCatPath](cat_id) from im_category_master
    
    Create FUNCTION [dbo].[fn_getIMCatPath] (@ID INT) 
    returns NVARCHAR(1000) 
    AS 
    BEGIN 
      DECLARE @Return   NVARCHAR(1000), 
              @parentID INT, 
              @iCount   INT 
    
      SET @iCount = 0 
    
      SELECT @Return = Cat_name, 
             @parentID = parent_id 
      FROM   im_category_master 
      WHERE  [cat_id] = @ID 
    
      WHILE @parentID IS NOT NULL 
        BEGIN 
            SELECT @Return = cat_name + '>' + @Return, 
                   @parentID = parent_id 
            FROM   im_category_master 
            WHERE  [cat_id] = @parentID 
    
            SET @iCount = @iCount + 1 
            IF @parentID = -1
            BEGIN
            SET @parentID = NULL 
            END
            IF @iCount > 10 
              BEGIN 
                  SET @parentID = NULL 
                  SET @Return = '' 
              END 
        END 
    
      RETURN @Return 
    END
    
    0 讨论(0)
  • 2020-12-08 08:51

    Consider this sample data and respective SQL to access child records along with their top parent.

    Sample DATA

    SQL code:

    ;WITH c AS (
       SELECT Id, Name, ParentId as CategoryId, 
              Id as MainCategoryId, Name AS MainCategory 
         FROM   pmsItemCategory 
         WHERE  ParentId is null
    
         UNION ALL 
    
         SELECT T.Id, T.Name, T.ParentId,  MainCategoryId, MainCategory 
         FROM   pmsItemCategory AS T 
                INNER JOIN c  ON T.ParentId = c.Id 
         WHERE  T.ParentId is not null
        ) 
    
    SELECT Id, Name, CategoryId, MainCategoryId, MainCategory 
    FROM   c 
    order by Id
    
    0 讨论(0)
  • 2020-12-08 08:52
    With cte as 
    (
    Select ChileId,Name,ParentId from tblHerarchy
    where ParentId is null 
    union ALL
    Select h.ChileId,h.Name,h.ParentId  from cte
    inner join tblHerarchy h on h.ParentId=cte.ChileId
    ) 
    Select * from cte
    
    0 讨论(0)
  • 2020-12-08 08:53
    select distinct 
           a.ChildID,a.ParentID,
           --isnull(nullif(c.parentID,b.parentID),a.parentID) as toppa,
           B.parentID
           --,c.parentID
          ,isnull(nullif(d.parentID,a.parentID),c.parentID) as toppa1,a.name
    from myTable a
       inner join myTable c
           on a.parentID=c.parentID
       inner join myTable b
           on b.childID=a.parentID
       inner join myTable d
           on d.childID=b.parentID
    
    0 讨论(0)
  • 2020-12-08 08:58

    Not sure I understand what you are looking for but it could be this.

    ;WITH c 
         AS (SELECT childid, 
                    parentid, 
                    parentid AS topParentID 
             FROM   @myTable 
             WHERE  childid = parentid 
             UNION ALL 
             SELECT T.childid, 
                    T.parentid, 
                    c.topparentid 
             FROM   @myTable AS T 
                    INNER JOIN c 
                            ON T.parentid = c.childid 
             WHERE  T.childid <> T.parentid) 
    SELECT childid, 
           topparentid 
    FROM   c 
    ORDER  BY childid 
    

    SE-Data

    It is the same as answer by marc_s with the difference that I use your table variable and the fact that you have childID = parentID for root nodes where the answer by marc_s has parent_ID = null for root nodes. In my opinion it is better to have parent_ID = null for root nodes.

    0 讨论(0)
提交回复
热议问题