分层数据库选择/插入语句(SQL Server)

时间:2009-07-06 19:58:09

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

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

我的表结构如下:

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

e.g

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

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

4 个答案:

答案 0 :(得分:5)

如果您使用的是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];

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

我不确定我是否理解你想要插入的内容。完成后,您能否提供有关预期结果的更多信息?

祝你好运!

答案 1 :(得分:2)

对于检索部分,您可以查看Common Table Expression。此功能可以使用SQL提供递归操作。

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

答案 2 :(得分:1)

我希望此网址有助于Self-Joins in SQL

答案 3 :(得分:0)

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

  1. 使用供应商特定的SQL扩展
  2. Materialized Path从根目录存储到每行的给定节点
  3. 存储Nested Sets,这是当节点标记为深度时,以给定节点为根的子树所涵盖的间隔
  4. 第一个选项很简单,如果你不需要数据库可移植性可能是最好的。第二个和第三个选项的优点是纯SQL,但需要保持一些非规范化状态。更新使用实现路径的表很简单,但是对于快速查询,数据库必须支持对字符串值进行前缀查询的索引。嵌套集避免需要任何字符串索引功能,但在插入或删除节点时可能需要更新大量行。

    如果你总是使用MSSQL,我会使用Adrian提到的供应商特定选项。