【问题标题】:How to retrieve hierarchical data from a SQL Table?如何从 SQL 表中检索分层数据?
【发布时间】:2012-06-29 03:35:42
【问题描述】:

我有下面的存储过程来返回工作正常的 Id、parentId 和 absoluteUrls 列表:

ALTER PROCEDURE [dbo].[SearchDataManager.HierarchyById] 
    @currentId AS int   
AS
BEGIN
 DECLARE @id INT 
 DECLARE @parentId INT
 DECLARE @absoluteUrl NVARCHAR(1000)

 DECLARE @Hierarchy TABLE (Id int, ParentId int, AbsoluteUrl nvarchar(1000))

 WHILE @currentId != 0
 BEGIN

     SELECT @id = Id, @parentId = ParentId, @absoluteUrl = AbsoluteUrl
     FROM dbo.[SearchDataManager.NiceUrls]
     WHERE id = @currentId

     INSERT INTO @Hierarchy  VALUES (@id, @parentId, @absoluteUrl)

    SET @currentId = @parentId
 END

    SELECT * FROM @Hierarchy  
END

“NiceUrls”表具有 Id 和 ParentId。 parentId 引用同一张表中的一条记录。

返回如下:

 ----------------------------------
    Id  | ParentId | AbsoluteUrl
    ----------------------------------
    294 | 5        | url1
    5   | 2        | url2
    2   | 0        | url3

上面的代码使用 WHILE 循环并定义了一个 Table 变量可以正常工作,但我只是想知道有没有更好的方法从表中检索层次结构数据?

上述代码的问题在于可维护性。如果我需要返回 NiceUrls 表的 1 列,那么我必须定义一个新变量,将该列添加到内联表中,等等。

有没有更好的重写sp的方法?

谢谢,

这是什么

【问题讨论】:

标签: sql-server tsql while-loop hierarchy


【解决方案1】:

看起来您想要源表中与原始 id 相关的所有记录。

1) 创建一个 CTE,为您提供所有 ID(请参阅链接 Triple 注意)

2) 将此 CTE 加入到原始表中

【讨论】:

  • 这样查询速度更快!
【解决方案2】:
with Hierarchy (Id, ParentId, AbsoluteUrl, Level)
 AS
 (
    -- anchor member
     SELECT Id,
        ParentId,
        AbsoluteUrl,
        0 AS Level   
     FROM dbo.[NiceUrls]
     WHERE id = @currentId
     UNION ALL
     -- recursive members
     SELECT su.Id,
        su.ParentId,
        su.AbsoluteUrl,
        Level + 1 AS Level   
     FROM dbo.[NiceUrls] AS su
     INNER JOIN Hierarchy ON Hierarchy.ParentId = su.Id  
 )
 SELECT * FROM Hierarchy

【讨论】:

  • 不错!如果我们需要 @currentId 元素的所有子元素(而不是所有父元素),只需反转 JOIN 中的条件:“INNER JOIN Hierarchy ON Hierarchy.Id = su.ParentId”。
猜你喜欢
  • 2012-10-15
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
相关资源
最近更新 更多