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
我有一个 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