SQL Server CTE-递归

SQL Server CTE-递归,sql,sql-server,common-table-expression,Sql,Sql Server,Common Table Expression,我有两个表,第一个表包含文档数据,第二个表包含目录数据 表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 NU

我有两个表,第一个表包含文档数据,第二个表包含目录数据

表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
不显示根目录,文档在其目录中按顺序排序,结果按完整路径的名称从最低深度排序。

使用递归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
使用CTE生成文件夹层次结构 然后将文档加入文件夹 并使用为此目的创建的路径对结果进行排序

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

显示您的查询,您尝试了什么?注意顺序列名是一个小心使用语法的问题抱歉,我只是浏览了一些旧的问题,我错过了这个问题。如果我记得清楚的话,第二个答案更长,但对我来说似乎更清楚,但两者都有效。