用于构建层次结构字符串的SQL - 最后一级缺失

时间:2016-11-20 23:36:05

标签: sql sql-server ssms hierarchy

我正在为文档管理系统的层次结构构建一个字符串。所以,基本上是按文件夹细分的文件夹 - 一直到文档。

两个问题:

1.数据库列出一个表中的所有文件夹(及其父文件夹),以及另一个文件夹中的所有文件(及其父文件夹) 我到目前为止使用的查询错过了最终的文件夹级别。

我使用以下查询:

select a.id_object, a.name, a.id_parent, 
b.name as 'parent_name', b.id_parent as 'parent id'  
into #a
FROM [folders] a  left join  [folders] b on b.id_object = a.id_parent    

然后:

INSERT INTO Tree2([id_parent],[parent_name],[id_object],[object_name])
select id_parent, [parent_name],id_object, [name]  from #a

然后找到绝对顶级并插入/

UPDATE Tree2 SET Lineage='/', Depth=0 WHERE parent_name Is Null
UPDATE Tree2 SET Full_Lineage='/', Depth=0 WHERE parent_name Is Null

然后是递归部分:

WHILE EXISTS (SELECT * FROM Tree2 WHERE Depth Is Null) 
UPDATE T SET     T.depth = P.Depth + 1, 
         T.Lineage = P.Lineage + T.id_parent + ' / ' ,
         FROM Tree2 AS T 
INNER JOIN Tree2 AS P ON (T.id_parent=P.id_object)
WHERE P.Depth>=0 
AND T.Depth Is Null
AND P.Lineage Is Not Null

这使我的数据看起来像这样:

Node    id_parent     id_object    object_name    depth    lineage      
100     f10101        f1010122       blah blah      5        F00/f0/f100/f1000/f10101

有人可以建议如何将最终文件夹级别包含在沿袭的末尾,因为f1010122是链中的最后一个文件夹,仍然需要包含在lineage列中吗?然后我打算在文档表的左边连接document_parent_id = id_object (f1010122)

希望这是有道理的。我正在使用SQL Server 2014 Management Studio。谢谢。

1 个答案:

答案 0 :(得分:1)

如果你想在其血统的末尾返回当前的id_object,那么这将是一个相当简单的事情:

Select node, id_parent, id_object, object_name, depth, lineage, 
    full_path = lineage + id_object + '/'
  From Tree2;

一般来说,你可以在一步中实现你想要的,而不是你在这里的多步骤过程(这似乎有一些错误,可能是因为你试图重新创建你的代码是为了在这里发布它:buggy样本确实让你的回答变得更难了。

以下示例直接来自您的源[folders]表,并在SELECT语句中返回您想要的输出(如果需要,可以将其插入表中):

With recursive_cte As (
    Select id_object, name, id_parent, 
        depth = 0, 
        lineage = Convert(varchar(128), '/')
      From [folders]
      Where id_parent Is Null
    Union All
    Select child.id_object, child.name, child.id_parent, 
        depth = parent.depth + 1, 
        lineage = Convert(varchar(128), parent.lineage + child.id_parent + '/')
      From [folders] As child
      Join recursive_cte As parent on child.id_parent = parent.id_object)
Select id_object, name, id_parent, depth, lineage,
    full_path = lineage + id_object + '/'
  From recursive_cte;