我有2个表,第一个包含文档数据,第二个包含目录。
表格1
DocID DirID Name Order
----- ----- ---- -----
1 4 Doc1 2
2 1 Doc2 1
3 5 Doc3 1
4 3 Doc4 1
5 4 Doc5 1
表2
DirID ParentID Name
----- -------- ----
1 NULL root
2 1 Dir1
3 2 Dir2
4 1 Dir3
5 3 Dir4
结构体
root
-Dir1
-Dir2
-Dir4
-Doc3
-Doc4
-Dir3
-Doc5
-Doc1
-Doc2
我正在尝试在T-SQL中创建CTE,这将生成此结果,但我无法弄清楚如何做到这一点。有人可以提出解决方案吗?
Doc2
Dir3/Doc5
Dir3/Doc1
Dir1/Dir2/Doc4
Dir1/Dir2/Dir4/Doc3
未显示Root,文档在其目录中按Order
排序,结果按照完整路径名称排序的最低深度排序。
使用CTE
生成文件夹层次结构
然后将文档加入文件夹
并使用创建的Path
为此目的订购结果
DECLARE @Separator AS VARCHAR(1) = '\\'
--Generating folder hierarchy
;WITH Info AS
(
SELECT f.DirID
, f.ParentID
, f.Name
, CAST(f.Name AS VARCHAR(255)) AS PathValue
FROM Folders f
WHERE f.ParentID IS NULL
UNION ALL
SELECT f.DirID
, f.ParentID
, f.Name
, CAST(i.PathValue + @Separator + f.Name AS VARCHAR(255))
FROM Folders f
INNER JOIN Info i ON f.ParentID = i.DirID
)
-- Join documents to the folder hirarchy
SELECT i.ParentID
, i.DirID
, i.Name
, d.DocID
, d.Name
, i.PathValue + @Separator + CAST(d.OrderNum AS VARCHAR(255)) + '.' + d.Name AS OrderPath
, i.PathValue + @Separator + d.Name AS DocumentPath
FROM Info i
INNER JOIN Documents d ON d.DirID = i.DirID
UNION ALL
-- Adding NULL row for folder, will show folder in the result even no documents
-- This can be removed if you want show only folders which containing documents
SELECT i.ParentID
, i.DirID
, i.Name
, NULL
, NULL
, i.PathValue AS OrderPath
, i.PathValue AS DocumentPath
FROM Info i
ORDER BY OrderPath
使用Recursive CTE
,您可以轻松创建如上所示的路径:
注意:我相信你的输出对于Doc4:Dir1/Dir2/Doc4
是错误的。每个逻辑应该是Dir1/Doc4
。
;WITH q1
AS (
SELECT a.DocID
,b.*
,a.NAME AS rootname
FROM tableb b
LEFT JOIN tablea a ON b.DirID = a.DirID
)
,q2
AS (
-- anchor
SELECT DocID
,DirID
,q1.rootname
,ParentID
,CAST((q1.NAME) AS VARCHAR(1000)) [Path]
FROM q1
WHERE ParentId IS NULL
UNION ALL
--recursive member
SELECT t.DocID
,t.DirID
,t.rootname
,t.ParentID
,CAST((a.path + '/' + t.NAME) AS VARCHAR(1000)) [Path]
FROM q1 AS t
INNER JOIN q2 AS a ON t.ParentId = a.DirID
)
SELECT replace([Path] + '/' + q2.rootname, 'root/', '') AS FinalPath
FROM q2
WHERE q2.rootname IS NOT NULL
ORDER BY FinalPath DESC