SQL Server - 从表中订购数据层次结构

时间:2017-06-13 18:46:34

标签: sql sql-server tsql hierarchy sql-server-2016

我有一个具有以下结构的表:

|  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      |

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

在这个例子中,我需要获取“Ap​​ple”层次结构下的所有内容,以便生成的集合为:

|  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      |

注意这是如何按级别对行进行排序,其中直接子进入父级。

我真的很感激帮助!谢谢!

2 个答案:

答案 0 :(得分:0)

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

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  

答案 1 :(得分:0)

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]

返回

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