Select node/descendant 对用于树层次结构中的每个排列
Select node/descendant pairs for every permutation in tree hierarchy
我有一个文件夹树结构表示在 SQL 服务器 table:
Id ParentId
------------
1 NULL
2 1
3 1
4 2
5 3
我想构建一个 SQL 查询以提供 文件夹 ID 到后代文件夹 ID 的所有排列:
FolderId DescendantFolderId
----------------------------
1 2
1 3
1 4
1 5
2 4
3 5
到目前为止,我已经编写了以下查询,但它只是 select 直接相关的 node/child 对:
WITH
RecursiveFolders
AS
(
SELECT
[Id],
[ParentId]
FROM
[Folders]
WHERE
[ParentId] is NULL
UNION ALL
SELECT
f.[Id],
f.[ParentId]
FROM
[Folders] f
INNER JOIN
RecursiveFolders r
ON
r.Id = f.ParentId
)
SELECT DISTINCT
[ParentId] as FolderId,
[Id] as DescendantFolderId
FROM
RecursiveFolders
WHERE
[ParentId] is not NULL
ORDER BY
[ParentId],
[Id]
输出:
FolderId DescendantFolderId
----------------------------
1 2
1 3
2 4
3 5
如何 select 文件夹到后代文件夹的所有排列?
您可以在 CROSS APPLY
中将数据类型 hierarchyID
与 IsDescendantOf()
一起使用...也可以是自我 JOIN
示例或dbFiddle
;with cte as (
Select ID
,ParentId
,HierID = convert(hierarchyid,concat('/',ID,'/'))
From Folders
Where ParentId is null
Union All
Select ID = r.ID
,ParentId = r.ParentId
,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
From Folders r
Join cte p on r.ParentId = p.ID
)
Select FolderID = A.ID
,DescendantFolderId = B.ID
From cte A
Cross Apply (
Select *
From cte
Where HierID.IsDescendantOf( A.HierID ) = 1
) B
Where A.ID<>B.ID
Order By A.HierID
结果
FolderID DescendantFolderId
1 2
1 3
1 5
1 4
2 4
3 5
我有一个文件夹树结构表示在 SQL 服务器 table:
Id ParentId
------------
1 NULL
2 1
3 1
4 2
5 3
我想构建一个 SQL 查询以提供 文件夹 ID 到后代文件夹 ID 的所有排列:
FolderId DescendantFolderId
----------------------------
1 2
1 3
1 4
1 5
2 4
3 5
到目前为止,我已经编写了以下查询,但它只是 select 直接相关的 node/child 对:
WITH
RecursiveFolders
AS
(
SELECT
[Id],
[ParentId]
FROM
[Folders]
WHERE
[ParentId] is NULL
UNION ALL
SELECT
f.[Id],
f.[ParentId]
FROM
[Folders] f
INNER JOIN
RecursiveFolders r
ON
r.Id = f.ParentId
)
SELECT DISTINCT
[ParentId] as FolderId,
[Id] as DescendantFolderId
FROM
RecursiveFolders
WHERE
[ParentId] is not NULL
ORDER BY
[ParentId],
[Id]
输出:
FolderId DescendantFolderId
----------------------------
1 2
1 3
2 4
3 5
如何 select 文件夹到后代文件夹的所有排列?
您可以在 CROSS APPLY
中将数据类型 hierarchyID
与 IsDescendantOf()
一起使用...也可以是自我 JOIN
示例或dbFiddle
;with cte as (
Select ID
,ParentId
,HierID = convert(hierarchyid,concat('/',ID,'/'))
From Folders
Where ParentId is null
Union All
Select ID = r.ID
,ParentId = r.ParentId
,HierID = convert(hierarchyid,concat(p.HierID.ToString(),r.ID,'/'))
From Folders r
Join cte p on r.ParentId = p.ID
)
Select FolderID = A.ID
,DescendantFolderId = B.ID
From cte A
Cross Apply (
Select *
From cte
Where HierID.IsDescendantOf( A.HierID ) = 1
) B
Where A.ID<>B.ID
Order By A.HierID
结果
FolderID DescendantFolderId
1 2
1 3
1 5
1 4
2 4
3 5