SQL 数据库查询结果按 ChildrenIDs 和 subChildrenIDs 分组
SQL database query grouping results by ChildrenIDs as well as subChildrenIDs
我在 SQL Server 2008 中有这个 [Folders]
table:
TABLE [dbo].[Folders]
(
[FolderID] [NUMERIC](18, 0) IDENTITY(1,1) NOT NULL,
[SubFolderOf] [NUMERIC](18, 0) NOT NULL,
[FolderName] [VARCHAR](128) NOT NULL
)
这是table
中的数据
[ID] [SubFolderOf] [FolderName]
------------------------------------------------
1 0 Main [ROOT]
2 1 Technical And Development
3 1 Sales and Marketing
4 1 Legal
5 1 Finance
6 1 Departments
7 1 Compliance
8 2 Test Scripts
9 2 Documentation
10 2 Files
11 8 AV Training
12 8 AV Finance 1
[SubFolderOf]
列是 [ID]
列的子列。
例如,请注意 ID#12 (AV Finance 1
) 是 ID#8 (Test Scripts
) 的子文件夹,而 ID#8 (Test Scripts
) 是 ID#2 (Technical and Development
) 的子文件夹。
我无法编写 return 以下结果的查询
[ID] [Field Name]
----------------------------------------------------------
1 Main
2 Main >> Technical and Development
11 Main >> Technical and Development >> AV Training
12 Main >> Technical and Development >> AV Finance 1
3 Main >> Sales and Marketing
4 Main >> Legal
有人可以帮我解决这个问题吗?
你有几个选择,你可以自己连接 table 几次(左连接)或者你可以使用“循环 cte”,这是一个常见的 table 表达式。我发现使用自连接更容易。您需要定义最多可以有多少次或级别,例如3 层深、5 层或 10 层。
像这样:
select F.FolderId, concat(isnull(F3.FolderName, “”), “>>”, isnull(F2.FolderName, “”), “>>”, F.FolderName) as [Field name] from Folders as F
left join Folders as F2 on F2.FolderId = F.SubFolderOf
left join Folders as F3 on F3.FolderId = F2.SubFolderOf
您可以删除多余的“>>”,例如使用 case
表达式或类似表达式。
不清楚您是否跳过所需结果中的级别,但您似乎正在寻找递归 CTE。我很确定这是 2008 兼容的。
例子
Declare @YourTable Table ([ID] int,[SubFolderOf] int,[FolderName] varchar(50))
Insert Into @YourTable Values
(1,0,'Main [ROOT]')
,(2,1,'Technical And Development')
,(3,1,'Sales and Marketing')
,(4,1,'Legal')
,(5,1,'Finance')
,(6,1,'Departments')
,(7,1,'Compliance')
,(8,2,'Test Scripts')
,(9,2,'Documentation')
,(10,2,'Files')
,(11,8,'AV Training')
,(12,8,'AV Finance 1')
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability
;with cteP as (
Select Seq = cast(10000+Row_Number() over (Order by ID) as varchar(500))
,ID
,SubFolderOf
,Lvl=1
,FolderName
,Path = cast(FolderName as varchar(500))
From @YourTable
Where [SubFolderOf]=0
Union All
Select Seq = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.ID)) as varchar(500))
,r.ID
,r.SubFolderOf
,p.Lvl+1
,r.FolderName
,cast(p.path + ' >> '+r.FolderName as varchar(500))
From @YourTable r
Join cteP p on r.SubFolderOf = p.ID)
Select A.ID
,A.SubFolderOf
,A.Lvl
,FolderName = Replicate(@Nest,A.Lvl-1) + A.FolderName
,Path
From cteP A
Order By Seq
Returns
我在 SQL Server 2008 中有这个 [Folders]
table:
TABLE [dbo].[Folders]
(
[FolderID] [NUMERIC](18, 0) IDENTITY(1,1) NOT NULL,
[SubFolderOf] [NUMERIC](18, 0) NOT NULL,
[FolderName] [VARCHAR](128) NOT NULL
)
这是table
中的数据[ID] [SubFolderOf] [FolderName]
------------------------------------------------
1 0 Main [ROOT]
2 1 Technical And Development
3 1 Sales and Marketing
4 1 Legal
5 1 Finance
6 1 Departments
7 1 Compliance
8 2 Test Scripts
9 2 Documentation
10 2 Files
11 8 AV Training
12 8 AV Finance 1
[SubFolderOf]
列是 [ID]
列的子列。
例如,请注意 ID#12 (AV Finance 1
) 是 ID#8 (Test Scripts
) 的子文件夹,而 ID#8 (Test Scripts
) 是 ID#2 (Technical and Development
) 的子文件夹。
我无法编写 return 以下结果的查询
[ID] [Field Name]
----------------------------------------------------------
1 Main
2 Main >> Technical and Development
11 Main >> Technical and Development >> AV Training
12 Main >> Technical and Development >> AV Finance 1
3 Main >> Sales and Marketing
4 Main >> Legal
有人可以帮我解决这个问题吗?
你有几个选择,你可以自己连接 table 几次(左连接)或者你可以使用“循环 cte”,这是一个常见的 table 表达式。我发现使用自连接更容易。您需要定义最多可以有多少次或级别,例如3 层深、5 层或 10 层。
像这样:
select F.FolderId, concat(isnull(F3.FolderName, “”), “>>”, isnull(F2.FolderName, “”), “>>”, F.FolderName) as [Field name] from Folders as F
left join Folders as F2 on F2.FolderId = F.SubFolderOf
left join Folders as F3 on F3.FolderId = F2.SubFolderOf
您可以删除多余的“>>”,例如使用 case
表达式或类似表达式。
不清楚您是否跳过所需结果中的级别,但您似乎正在寻找递归 CTE。我很确定这是 2008 兼容的。
例子
Declare @YourTable Table ([ID] int,[SubFolderOf] int,[FolderName] varchar(50))
Insert Into @YourTable Values
(1,0,'Main [ROOT]')
,(2,1,'Technical And Development')
,(3,1,'Sales and Marketing')
,(4,1,'Legal')
,(5,1,'Finance')
,(6,1,'Departments')
,(7,1,'Compliance')
,(8,2,'Test Scripts')
,(9,2,'Documentation')
,(10,2,'Files')
,(11,8,'AV Training')
,(12,8,'AV Finance 1')
Declare @Nest varchar(25) = '|-----' --<< Optional: Added for readability
;with cteP as (
Select Seq = cast(10000+Row_Number() over (Order by ID) as varchar(500))
,ID
,SubFolderOf
,Lvl=1
,FolderName
,Path = cast(FolderName as varchar(500))
From @YourTable
Where [SubFolderOf]=0
Union All
Select Seq = cast(concat(p.Seq,'.',10000+Row_Number() over (Order by r.ID)) as varchar(500))
,r.ID
,r.SubFolderOf
,p.Lvl+1
,r.FolderName
,cast(p.path + ' >> '+r.FolderName as varchar(500))
From @YourTable r
Join cteP p on r.SubFolderOf = p.ID)
Select A.ID
,A.SubFolderOf
,A.Lvl
,FolderName = Replicate(@Nest,A.Lvl-1) + A.FolderName
,Path
From cteP A
Order By Seq
Returns