查询 SQL 中的分层数据

Querying hierarchical data in SQL

如何编写递归 SQL 查询,将不同层次的层次关系显示为单独的结果?


我的数据库 (Container) 中有一个 table,它与自身具有层次关系(任何容器都可以有多个内部容器)。我正在尝试创建一个视图,显示每个容器及其所有外部(不仅仅是它的直接外部)以及内部容器的深度。例如:

如果我的容器 table 中有以下记录:

我希望视图显示:

没有

基本上,我希望能够通过执行 select innerId from v_MyView where outerId = @outer_id 找出特定容器中的内部容器,并通过执行 select outerId from v_MyView where innerId = @inner_id 找出特定容器中的容器

更新

我正在使用 SQL Server 2012,而且我非常熟悉递归 CTE。我遇到的问题不是我不知道如何编写递归 CTE,而是我需要输出在多行中而不是视图中的连接字段。

这是我已有的:

with MYCTE as
(
    select 
         Id, 
         Cast(null as varchar(max)) as cntr_path,
         0 as lvl
      from Container
      where Container.outerId is null
    union all
    select 
        Container.Id,
        IsNull(cntr_path + ',','') + '[' + cast(Container.outerId as varchar(max)) + ']',
        lvl + 1
      from Container join MYCTE 
        on Container.outerId = MYCTE.Id
)
select * from MYCTE where cntr_path is not null

但这每个内部容器只产生一行。我想要的是每个外部容器每个内部容器一行

我想描述我想要的视图的最佳方式是 "linking table" 将每个外部容器与其每个内部容器联系起来 - "outerId" 和 "innerId" 像外键一样(都指向 Container 中的 Id)。

如果您使用的是 SQL 服务器,请查看此 Microsoft link。它详细介绍了递归通用 Table 表达式。

在 Oracle 中,这是描述 Hierarchical Queries 的 link。

MySQL hierarchical queries.

文章中给出的示例将为您提供解决问题的必要垫脚石。

睡了一会儿之后,我意识到我错误地识别了我的递归 CTE 的锚点。而不是最外面的容器是我的锚点(如我更新的示例),锚点应该是每个带有外部容器的容器:

select 
     Id as InnerId, 
     Container.outerId as OuterId
     1 as lvl
  from Container

这构成了我的 CTE 的递归部分:

union all
select 
    MYCTE.InnerId,
    Container.OuterId
    lvl + 1
  from Container join MYCTE 
    on Container.Id = MYCTE.OuterId
  where Container.OuterId is not null