我试图解决的问题是使用CTE从表中提取数据以检索分层数据的请求。由于数据引用本身的性质,达到最大递归是一个很大的问题,但我不想随意停止数据,因为它不会完整。要了解数据,以下是示例输出的样子:
顶级
11552
- 11414
- 68775
- 23667
- 65887*
- 58669*
- 58669
- 65887*
11414
- 58667
- 11552*
- 45998
- 23667
- 65887*
- 33789
- 26998
- 11552*
65887
- 26988
- 23667
- 65887*
- 45998*
- 58667
- 11552*
问题在于不重复已经出现在层次结构中但仍至少包含第一个值(由星号标记的项目)的项目链。
根据要求更新: 表中的数据结构如下:
Id ProcId AsscId
1 11552 11414
2 11552 68775
3 11552 58669
4 68775 23667
5 68775 58669
6 23667 65887
7 58669 65887
8 11414 58667
9 11414 45998
10 11414 26998
11 58667 11552
12 45998 23667
13 45998 33789
14 26998 11552
15 65887 26998
16 65887 58667
17 26988 23667
18 26988 45998
我的初始CTE查询(现在包括停止)如下所示。查询仅提取初始数据,但我无法弄清楚如何更改它以满足请求。
WITH myCTE AS
(
SELECT ProcId, AsscId, 0 as [Level]
FROM Associations
UNION ALL
SELECT a.ProcId, a.AsscId, ([Level] + 1) as RecursionLevel
FROM Associations a
INNER JOIN myCTE m ON a.ProcId = m.ProcId
WHERE ([Level] + 1) <= 2
)
SELECT *
FROM myCTE
ORDER BY ProcId
我在这里查看了这些示例How to use Common Table Expression and check no duplication in SQL Server和Removing duplicates from a CTE based on a specific criteria,但我不确定在这种情况下是否有帮助。
潜在解决方案:
因此,经过进一步的搜索和讨论,我了解到在这种情况下,CTE确实不是最好的选择。相反,我创建了一个临时表,用第一行父数据填充它,然后调用一个单独的查询来获取其他数据。如果该查询发现有更多数据,则它再次调用自身并获取下一级数据。当它获得下一级数据时,它只会检索临时表中尚不存在的数据。临时表包含ProcId的值,父ID,检索它的级别以及如果临时表中已存在id,则保存一个布尔值的列。将使用布尔值指示是否显示完整数据。
答案 0 :(得分:1)
这就是您的样本数据的样子:
它有几个互连的循环。我不知道如何在没有一些额外信息的情况下以树的形式呈现这一点。
您需要额外的信息来告诉循环中的哪些节点应该成为树中的根节点。换句话说,一些规则指定如何打破循环;应该打破图中的哪些链接。
对于循环11552 -> 11414 -> 58667
,您可以选择任何节点成为根。但是,有几个其他循环通过相同的节点,例如11552 -> 11414 -> 45998 -> 23667 -> 65887 -> 58667
; 11552 -> 58669 -> 65887 -> 58667
以及更多......
根据您决定打破树形状的链接,将会发生变化。
按原样保存数据,我会不尝试将其呈现为树,因为如果不丢失某些链接的信息,这是不可能的。我使用graphviz生成上面显示的图片,我会尝试使用此库或类似的库来执行此任务。