【问题标题】:Hierarchical Database Select / Insert Statement (SQL Server)分层数据库选择/插入语句 (SQL Server)
【发布时间】:2009-07-06 19:58:09
【问题描述】:

我最近偶然发现从一个表中选择关系详细信息并插入另一个表的问题,希望有人能提供帮助。

我有一个表结构如下:

ID (PK)   Name       ParentID<br>
1         Myname     0<br>
2         nametwo    1<br>
3         namethree  2

例如

这是我需要从中选择并获取所有关系数据的表。因为可能有无限数量的子链接(我可以为此创建一个函数来创建循环吗?)

然后,一旦我拥有了需要插入另一个表的所有数据,并且 ID 现在必须更改,因为 id 必须按顺序排列(例如,我不能让 id "2" 成为 3 的子),我希望我可以使用相同的功能来选择插入。

【问题讨论】:

    标签: asp.net sql-server sql-server-2005


    【解决方案1】:

    如果您使用的是 SQL Server 2005 或更高版本,您可以使用递归查询来获取您的信息。这是一个例子:

    With tree (id, Name, ParentID, [level])
    As (
        Select id, Name, ParentID, 1
        From [myTable]
        Where ParentID = 0
    
        Union All
    
        Select child.id
              ,child.Name
              ,child.ParentID
              ,parent.[level] + 1 As [level]
        From [myTable] As [child]
        Inner Join [tree] As [parent]
        On [child].ParentID = [parent].id)
    Select * From [tree];
    

    此查询将递归返回第一部分(其中 ParentID = 0)请求的行和所有子行。这对您有帮助吗?

    我不确定我是否理解您希望插入的内容。完成后能否提供更多关于预期结果的信息?

    祝你好运!

    【讨论】:

    • 嗨,就我完成的结构而言,我需要一个与选择表具有相同结构的新表,但它必须按 ID 顺序排列,例如id 1 可以有一个子部分,但它必须是 id > 1 等等,并且必须按顺序排列,例如 ID 1 顶层、子层、下层、ID 2 顶层、ID 3 顶层、子层。等希望这会有所帮助。期待您的回复。
    • 未定义表中的行顺序。我认为您无法保证行的顺序,因为它们存在于表本身中。你能做的最好的事情是当你使用 SELECT 语句,使用 ORDER BY 子句将它们拉出时,按特定顺序获取它们。在我的示例中,您可以将 ORDER BY [level] 添加到 select 语句中,这将保证您不会在其子行之后获得任何父行。这有帮助吗?
    • 您好,再次感谢您的回复。在您回帖之前,我决定继续使用 order by 子句:) 我很高兴现在我可以使用 executescalar 以正确的顺序插入并返回插入的最后一个 id,为下一行插入做好准备。
    【解决方案2】:

    检索部分可以看Common Table Expression。此功能可以提供使用 SQL 的递归操作。

    对于插入部分,可以使用上面的CTE重新生成ID,并进行相应的插入。

    【讨论】:

      【解决方案3】:

      希望这个网址对Self-Joins in SQL有帮助

      【讨论】:

        【解决方案4】:

        这是在sql中寻找图的传递闭包的问题。 SQL 不直接支持这一点,这给您留下了三种常见的策略:

        1. 使用供应商特定的 SQL 扩展
        2. Materialized Path从根存储到每一行的给定节点
        3. 存储Nested Sets,即当节点标记为深度优先时,以给定节点为根的子树所覆盖的区间

        第一个选项很简单,如果您不需要数据库可移植性可能是最好的。第二个和第三个选项的优点是纯 SQL,但需要维护一些非规范化状态。更新使用具体化路径的表很简单,但对于快速查询,您的数据库必须支持对字符串值进行前缀查询的索引。嵌套集不需要任何字符串索引功能,但可能需要在插入或删除节点时更新大量行。

        如果您对始终使用 MSSQL 感到满意,我会使用 Adrian 提到的供应商特定选项。

        【讨论】:

        • 为什么不使用公用表表达式?这是实现此目的的 SQL 标准方法 - 它不是特定于供应商的功能,并且适用于许多数据库系统。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多