【问题标题】:Flatten the tree path in SQL server Hierarchy ID展平 SQL Server Hierarchy ID 中的树路径
【发布时间】:2014-09-23 08:33:13
【问题描述】:

我正在使用 SQL Hierarchy 数据类型对我的应用程序中的分类结构进行建模。 分类可以在不同的层级中具有相同的名称

在设置过程中,需要通过 Excel 表格上传这些数据。

在插入任何节点之前,我想检查特定路径上的节点是否已经存在,以免重复条目。 检查节点@特定绝对路径是否已经存在的最简单方法是什么?

例如,在“Bank 2”下插入“Retail”之前,我应该能够检查“/Bank 2/Retail”不存在

有没有办法提供整个树结构的扁平化表示,以便我可以检查绝对路径然后继续?

【问题讨论】:

  • 从您的示例和标签看来,您已经知道答案 - 将其存储在 hierarchyid 中并使用 ToString 将每个节点转换为字符串路径,然后进行比较。您可能需要先插入临时表
  • 我拥有的 Path 列是 ToString() 表示。我需要能够构建扁平树路径。我目前不知道如何获得 Falttened Tree Path

标签: sql sql-server sql-server-2008 sql-server-2012 hierarchyid


【解决方案1】:

是的,你可以做到using a recursive CTE

在查询的每次迭代中,您都可以附加一个新级别的层次结构名称。

互联网上有很多这种技术的例子。

例如,使用此示例数据:

CREATE TABLE Test
(id INT,
parent_id INT null,
NAME VARCHAR(50)
)

INSERT INTO Test VALUES(1, NULL, 'L1')
INSERT INTO Test VALUES(2, 1, 'L1-A')
INSERT INTO Test VALUES(3, 2, 'L1-A-1')
INSERT INTO Test VALUES(4, 2, 'L1-A-2')
INSERT INTO Test VALUES(5, 1, 'L1-B')
INSERT INTO Test VALUES(6, 5, 'L1-B-1')
INSERT INTO Test VALUES(7, 5, 'L1-B-2')

您可以像这样编写递归 CTE:

WITH H AS
(
    -- Anchor: the first level of the hierarchy
    SELECT id, parent_id, name, CAST(name AS NVARCHAR(300)) AS path 
    FROM Test 
    WHERE parent_id IS NULL      
UNION ALL
    -- Recursive: join the original table to the anchor, and combine data from both  
    SELECT T.id, T.parent_id, T.name, CAST(H.path + '\' + T.name AS NVARCHAR(300)) 
    FROM Test T INNER JOIN H ON T.parent_id = H.id
)
-- You can query H as if it was a normal table or View
SELECT * FROM H
   WHERE PATH = 'L1\L1-A' -- for example to see if this exists

查询的结果(没有 where 过滤器)如下所示:

1  NULL  L1      L1
2  1     L1-A    L1\L1-A
5  1     L1-B    L1\L1-B
6  5     L1-B-1  L1\L1-B\L1-B-1
7  5     L1-B-2  L1\L1-B\L1-B-2
3  2     L1-A-1  L1\L1-A\L1-A-1
4  2     L1-A-2  L1\L1-A\L1-A-2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多