SQL 中表示的展平树结构

Flatten tree structure represented in SQL

我正在使用工程计算包并尝试在允许 SQL 查询的内置报告工具中从中提取一些信息

简写例子SQL table如下:

Id |  Description  | Ref
---|---------------------
1  |  system 1     |        
3  |  block 4      | 6
3  |  block 4      | 1
5  |  formula1     | 3
6  |  f            | 
7  |  something    | 1
9  |  cheese       | 5

"Ref" 列标识的行是其他项目的子记录。

我想要做的是 运行 一个查询,该查询将生成一个列表,该列表将显示出现在每个页面上的所有项目。从上面的 table 可以看出 "ID" 不是唯一键;每个项目都可以出现在 table 内的多个位置。在上面的例子中:

它实际上代表了一个树结构:

ID 1
+-------- ID 7
    |---- ID 3
        +---- ID 5
            +---- ID 9
ID 6
+---- ID 3
    +---- ID 5
        +---- ID 9

我希望找出每个顶级项目下出现哪些项目(因此最终结果应该是 table,其中 "Ref" 列中仅出现顶级项目) :

Id |  Description  | Ref
---|---------------------
1  |  system 1     |        
3  |  block 4      | 6
3  |  block 4      | 1
5  |  formula1     | 1
5  |  formula1     | 6
6  |  f            | 
9  |  cheese       | 1
9  |  cheese       | 6
7  |  something    | 1

树结构总共可以有5层深

我一直在尝试使用左联接来构建页面引用列表,但我认为我还需要合并结果 tables(因为很明显像 ID=9 的行, ID=5, and ID = 6 必须在最终结果集中重复)。开始有点乱了!

WITH   A
AS     (SELECT *
         FROM   [RbdBlocks]),
       B
AS     (SELECT [x].[Id],
               [x].[Description],
               [x].[Page] AS Page1,
               [y].[Page] AS Page2,
        FROM   A AS x
               LEFT OUTER JOIN
               A AS y
               ON y.Id = x.Page)
SELECT *
FROM   B

上面给了我一些嵌套引用,但我不确定是否有更好的方法来将这些数据放在一起,并管理递归而不是仅仅将查询集复制 4 次?

看看 Recursive Common Table Expressions(CTE)。他们应该能够完全满足您的需求。

查看 SQL 文档页面上的 Example D

基本上你在你的情况下会做的是:

  • 在 CTE 的 "anchor member" 中,select 所有顶级项目
  • 在 CTE 的 "recursive member" 中,将所有嵌套子项加入顶级项

递归 CTE 并不容易理解,因此请务必仔细阅读文档。