我有一些表格,代表了文件系统的工作,我需要选择每个文件夹的完整路径作为扁平化线。SQL - 转换非空邻接表到路径
第一个表列出了每个文件夹的详细信息:
CREATE TABLE Folders(
FolderID int IDENTITY(1,1) NOT NULL,
[Name] nvarchar(255) NOT NULL)
第二个表列出文件夹的关系传递闭:
CREATE TABLE FolderClosures(
FolderClosuresID int IDENTITY(1,1) NOT NULL,
AncestorFolderID int NOT NULL, --Foreign key to Folders.FolderID
DescendantFolderID int NOT NULL --Foreign key to Folders.FolderID
IsDirect bit NOT NULL)
对于样本数据,我们假设以下文件夹存在:
Documents/
Documents/Finance/
Documents/HumanResources/
Documents/HumanResources/Training/
这些将持续在这些表中如下:
| FolderID | Name |
+----------+----------------+
| 1 | Documents |
| 2 | Finance |
| 3 | HumanResources |
| 4 | Training |
| FolderClosureID | AncestorFolderID | DescendantFolderID | IsDirect |
+-----------------+------------------+--------------------+----------+
| 1 | 1 | 1 | 0 |
| 2 | 2 | 2 | 0 |
| 3 | 1 | 2 | 1 |
| 4 | 3 | 3 | 0 |
| 5 | 1 | 3 | 1 |
| 6 | 4 | 4 | 0 |
| 7 | 1 | 4 | 0 |
| 8 | 3 | 4 | 1 |
一些细节需要注意:
每个文件夹中含有
FolderClosures
,其中AncestorFolderID = DescendantFolderID AND IsDirect = 0
“身份排”。不是一个顶层文件夹中的每个文件在
FolderClosures
只有一行,其中IsDirect = 1
FolderClosures
可以包含每个文件夹多行,其中AncestorFolderID <> DescendantFolderID AND IsDirect = 0
。这些都代表“祖父母”或更远的关系。由于没有列是空的,没有行明确规定一个给定的文件夹是一个顶层文件夹。这只能通过检查
FolderClosures
中没有行来辨别,其中IsDirect = 1 AND DescendantFolderID = SomeID
其中SomeID
是有问题的文件夹的ID。
我希望能够运行,返回此数据的查询:
| FolderID | Path |
+----------+------------------------------------+
| 1 | Documents/ |
| 2 | Documents/Finance/ |
| 3 | Documents/HumanResources/ |
| 4 | Documents/HumanResources/Training/ |
文件夹可嵌套在无限的深度,但实际上可能只达到10级。查询可能需要返回几千个文件夹的路径。
我发现当数据持续为邻接表创建这种类型的查询提供了很多意见,但我一直没能找到一个传递闭包设置这样一个答案。我发现的邻接列表解决方案依赖于持续存在可为空的父文件夹ID的行,但这不起作用。
如何获得所需的输出?
如果有帮助,我使用的SQL Server 2016