【问题标题】:Flattening a SQL hierarchical data structure in SQL without cursors在没有游标的 SQL 中展平 SQL 分层数据结构
【发布时间】:2012-11-07 23:47:01
【问题描述】:

假设我有下表

SectionID ParentIDSection DatumID
   1           NULL         1
   2            1           2
   3            1           3
   4            2           4

现在,假设我想选择 SectionID = 1 下的所有 DatumID,即使它是其后代子项的一部分,这样我会得到

SectionID DatumID
  1         1
  1         2
  1         3
  1         4

是否可以在不使用游标显式递归遍历第一个表的情况下做到这一点?

【问题讨论】:

标签: sql sql-server sql-server-2008 hierarchical-data


【解决方案1】:

这让我困惑了一分钟,因为这与我对递归的看法相反,但我想出了这个非常简单的解决方案:

;WITH Rollups AS (
    SELECT SectionId, ParentIdSection, DatumId
    FROM SectionDataTable
    UNION ALL
    SELECT parent.SectionId, parent.ParentIdSection, child.DatumId
    FROM SectionDataTable parent 
    INNER JOIN Rollups child ON child.ParentIdSection = parent.SectionId
)
SELECT *
FROM Rollups 
WHERE SectionID = 1

(替换为您想要的部分 id)

【讨论】:

    【解决方案2】:
    declare @demo table
    (
        SectionId int not null primary key clustered
        , ParentId int null --foreign key references @demo(SectionId)
        , DatumId int
    );
    
    insert @demo
          select 1, null, 1
    union select 2, 1, 2
    union select 3, 1, 3
    union select 4, 2, 4
    union select 5, null, 5
    union select 6, 5, 6
    ;
    
    with demoHierarchy
    as
    (
        select SectionId
        , SectionId ParentId
        , SectionId OriginalAncestorId
        , DatumId
        from @demo
        where ParentId is null --remove this line if you want OriginalAncestorId to be AnyAncestorId (if that doesn't make sense, try it and see)
    
        union all
    
        select d.SectionId
        , d.ParentId
        , h.OriginalAncestorId
        , d.DatumId
        from @demo d
        inner join demoHierarchy h
        on d.ParentId = h.SectionId
        where d.ParentId is not null --implied by the join, but here to make it explicit
    )
    select OriginalAncestorId SectionId
    , DatumId 
    from demoHierarchy
    where OriginalAncestorId = 1 --not needed given your sample data only contains this data, but required when you have multiple root ancestors
    

    有关分层查询的更多信息,请点击此处:http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/

    【讨论】:

      【解决方案3】:

      您可以在 MS SQL 2008 中使用 Hierarchy ID。SQL Server 2008 Hierarchy Data Type Performance? 询问了另一个关于相对性能的问题。

      这是处理递归层次结构的另一个参考:http://www.bimonkey.com/2009/09/handling-recursive-hierarchies-in-sql-server/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-27
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多