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