SQL Server 2005 CTE分层表,管理重复项,没有maxrecursion

时间:2015-07-05 23:48:16

标签: sql sql-server-2005

我试图解决的问题是使用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 ServerRemoving duplicates from a CTE based on a specific criteria,但我不确定在这种情况下是否有帮助。

潜在解决方案:

因此,经过进一步的搜索和讨论,我了解到在这种情况下,CTE确实不是最好的选择。相反,我创建了一个临时表,用第一行父数据填充它,然后调用一个单独的查询来获取其他数据。如果该查询发现有更多数据,则它再次调用自身并获取下一级数据。当它获得下一级数据时,它只会检索临时表中尚不存在的数据。临时表包含ProcId的值,父ID,检索它的级别以及如果临时表中已存在id,则保存一个布尔值的列。将使用布尔值指示是否显示完整数据。

1 个答案:

答案 0 :(得分:1)

这就是您的样本数据的样子:

graph

它有几个互连的循环。我不知道如何在没有一些额外信息的情况下以树的形式呈现这一点。

您需要额外的信息来告诉循环中的哪些节点应该成为树中的根节点。换句话说,一些规则指定如何打破循环;应该打破图中的哪些链接。

对于循环11552 -> 11414 -> 58667,您可以选择任何节点成为根。但是,有几个其他循环通过相同的节点,例如11552 -> 11414 -> 45998 -> 23667 -> 65887 -> 58667; 11552 -> 58669 -> 65887 -> 58667以及更多......

根据您决定打破树形状的链接,将会发生变化。

按原样保存数据,我会尝试将其呈现为树,因为如果不丢失某些链接的信息,这是不可能的。我使用graphviz生成上面显示的图片,我会尝试使用此库或类似的库来执行此任务。