Sql server 2008 如何在SameTable中获取父类别的根

Sql server 2008 如何在SameTable中获取父类别的根,sql-server-2008,Sql Server 2008,我有一个类别表,因为我正在创建父类别的父类别和子类别 现在我得到了这样的分类 Select CatID,CatName,ParentCatID from Category CatID CatName ParentCatID 35 Test1 0 36 Test2 35 37 Test3 36 38 Test4 0 39 Test5 38 40 Test6 3

我有一个类别表,因为我正在创建父类别的父类别和子类别

现在我得到了这样的分类

Select CatID,CatName,ParentCatID from Category 

CatID   CatName ParentCatID
 35         Test1   0
 36         Test2   35
 37         Test3   36
 38         Test4   0
 39         Test5   38
 40         Test6   39
我想要这样的输出

   CatID CatName   ParentCatID   ParentRoot
    35   Test1        0          None
    36   Test2        35         Test1
    37   Test3        36         Test1>Test2
    38   Test4         0         None
    39   Test5        38         Test4
    40   Test6        39         Test4>Test5

您的表格中的级别数有限制吗?如果您知道自连接的深度永远不会超过两个级别,则可以使用自连接进行此操作:

SELECT
   C.CatID,
   C.CatName,
   C.ParentCatID,
   CASE 
      WHEN P.CatName is NULL THEN 'None' 
      ELSE WHEN GP.CatName is NULL THEN P.CatName 
      ELSE P.CatName + '>' + GP.CatName
   END
FROM
   Category C   -- child
   LEFT OUTER JOIN Category P ON C.ParentCatID = P.CatID    -- parent
   LEFT OUTER JOIN Category GP ON P.ParentCatID = GP.CatID  -- grand parent

但这只有在有两个或更少级别时才有效。不仅如此,您还应该考虑使用一个公共表表达式。

如果您有一个未知级别的层次结构,那么您可以使用递归公共表表达式:

WITH CategoryCTE AS
(   SELECT  CatID, 
            CatName, 
            ParentCatID, 
            RecursionLevel = 1, 
            ParentRoot = CAST('None' AS VARCHAR(MAX)),
            LastParentCatID = ParentCatID
    FROM    Category
    UNION ALL
    SELECT  cte.CatID, 
            cte.CatName,
            cte.ParentCatID,
            cte.RecursionLevel + 1,
            ParentRoot = CASE WHEN cte.RecursionLevel = 1 THEN '' ELSE cte.ParentRoot + '>' END + c.CatName,
            LastParentCatID = c.ParentCatID
    FROM    CategoryCTE cte
            INNER JOIN Category c
                ON c.CatID = cte.LastParentCatID
), MaxRecursion AS
(   SELECT  CatID, 
            CatName, 
            ParentCatID, 
            ParentRoot, 
            RowNum = ROW_NUMBER() OVER(PARTITION BY CatID ORDER BY RecursionLevel DESC)
    FROM    CategoryCTE
)
SELECT  CatID, CatName, ParentCatID, ParentRoot
FROM    MaxRecursion
WHERE   RowNum = 1;