我的数据库中有一个表(Container
),它与自身有层次关系(任何容器都可以有很多内部容器)。我正在尝试创建一个视图,显示每个容器的所有外部(不仅仅是它的直接外部)以及内部容器的深度。例如:
如果我的Container表中包含以下记录:
我希望视图显示:
不是
基本上,我希望能够通过执行: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
但是每个内部容器只产生一行。我想要的是每个外部容器每个内部容器一行
我想描述我想要的视图的最佳方式是将每个外部容器与其内部容器相关联的“链接表” - “outerId”和“innerId”都像外键一样(两者都指向容器中的Id。
答案 0 :(得分:1)
如果您使用的是SQL Server,请查看此Microsoft link。它详细介绍了递归公用表表达式。
在Oracle中,这是一个描述Hierarchical Queries的链接。
MySQL hierarchical queries。
文章中给出的例子将为您解决问题提供必要的垫脚石。
答案 1 :(得分:0)
在睡了一会儿之后,我意识到我错误地识别了我的递归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