SQL 服务器 - 从 Table 订购数据层次结构

SQL Server - Order Data Hierarchy From Table

我有一个 table 结构如下:

|  ObjectID  |  ParentID |  Description  |  Level  |
----------------------------------------------------
|  1000      |  NULL     |  Food         |  0      |
|  1001      |  1000     |  Fruit        |  1      |
|  1002      |  1000     |  Vegetable    |  1      |
|  1003      |  1001     |  Apple        |  2      |
|  1004      |  1001     |  Banana       |  2      |
|  1005      |  1002     |  Cabbage      |  2      |
|  1006      |  1002     |  Spinach      |  2      |
|  1007      |  1003     |  Red          |  3      |
|  1008      |  1003     |  Green        |  3      |
|  1009      |  1007     |  Single       |  4      |
|  1010      |  1007     |  Bunch        |  4      |
|  1011      |  1010     |  Organic      |  5      |
|  1012      |  1010     |  Non-Organic  |  5      |

它基本上在单个 table 中列出了一堆具有层次结构的对象。 现在我需要能够查询此 table 并提出基于单个 ObjectID 的层次结构。像这样:

在此示例中,我需要获取 'Apple' 层次结构下的所有内容,以便结果集为:

|  ObjectID  |  ParentID |  Description  |  Level  |
----------------------------------------------------
|  1003      |  1001     |  Apple        |  2      |
|  1007      |  1003     |  Red          |  3      |
|  1009      |  1007     |  Single       |  4      |
|  1010      |  1007     |  Bunch        |  4      |
|  1011      |  1010     |  Organic      |  5      |
|  1012      |  1010     |  Non-Organic  |  5      |
|  1008      |  1003     |  Green        |  3      |

注意这是如何按级别对行进行排序的,其中直接子项排在父项之后。

非常感谢您的帮助!谢谢!

按照联机书中的示例进行操作:

https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql

USE AdventureWorks2012;  
GO  
WITH DirectReports(ManagerID, EmployeeID, Title, EmployeeLevel) AS   
(  
    SELECT ManagerID, EmployeeID, Title, 0 AS EmployeeLevel  
    FROM dbo.MyEmployees   
    WHERE ManagerID IS NULL  
    UNION ALL  
    SELECT e.ManagerID, e.EmployeeID, e.Title, EmployeeLevel + 1  
    FROM dbo.MyEmployees AS e  
        INNER JOIN DirectReports AS d  
        ON e.ManagerID = d.EmployeeID   
)  
SELECT ManagerID, EmployeeID, Title, EmployeeLevel   
FROM DirectReports  
ORDER BY ManagerID;  
GO  
Declare @Top int = 1003  --<<  Set To NULL for Full Hier

;with cteP as (
      Select [ObjectID]
            ,[ParentId]
            ,[Level]
            ,[Description] 
            ,[Sequence]  = cast(10000+Row_Number() over (Order by [ObjectID]) as varchar(500))
      From   @YourTable 
      Where  IsNull(@Top,-1) = case when @Top is null then isnull([ParentId] ,-1) else [ObjectID] end
      Union  All
      Select r.[ObjectID]
            ,r.[ParentId]
            ,r.[Level]
            ,r.[Description] 
            ,cast(concat(p.[Sequence],'.',10000+Row_Number() over (Order by r.[ObjectID])) as varchar(500))
      From   @YourTable r
      Join   cteP p on r.[ParentId]  = p.[ObjectID])
Select [ObjectID]
      ,[ParentId]
      ,[Description]
      ,[Level]
 From cteP 
 Order By [Sequence]

Returns

ObjectID    ParentId    Description Level
1003        1001        Apple       2
1007        1003        Red         3
1009        1007        Single      4
1010        1007        Bunch       4
1011        1010        Organic     5
1012        1010        Non-Organic 5
1008        1003        Green       3