用SQL表示的扁平树结构

用SQL表示的扁平树结构,sql,tsql,hierarchical-data,Sql,Tsql,Hierarchical Data,我正在使用一个工程计算包,并试图在一个内置的报告工具中从中提取一些信息,该工具允许SQL查询 SQL表的简化示例如下所示: Id | Description | Ref ---|--------------------- 1 | system 1 | 3 | block 4 | 6 3 | block 4 | 1 5 | formula1 | 3 6 | f | 7 | something

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

SQL表的简化示例如下所示:

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”列标识作为其他项的子记录的行

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

  • ID5是ID3的一个子项
  • ID 3是ID 1和ID 6的子项
  • ID 1和ID 6不是任何东西的子项
因此,它有效地表示了一个树结构:

ID 1
+-------- ID 7
    |---- ID 3
        +---- ID 5
            +---- ID 9
ID 6
+---- ID 3
    +---- ID 5
        +---- ID 9
我希望计算出每个顶级项目下出现的项目(因此最终结果应该是一个表,其中“Ref”列中只出现顶级项目):

树状结构总共可以有5层深

我一直在尝试使用左连接来建立页面引用列表,但我认为我还需要联合结果表(因为很明显,像ID=9、ID=5和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次?

看看(CTE)。他们应该能够完全满足你的需要

请查看SQL文档页面上的

基本上,在您的案例中,您要做的是:

  • 在CTE的“锚定成员”中,选择所有顶级项目
  • 在CTE的“递归成员”中,将所有嵌套子项连接到顶级项

递归CTE不是很容易理解,所以一定要仔细阅读文档。

是的,这些文档看起来确实很像,似乎只是为了工作,现在我正试图查询的软件中遇到了一个bug!
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