3

给定以下递归 CTE(对我的示例进行了一些简化):

    WITH myCTE (sort, parentid, myid, level, somedata)
AS
(
-- Anchor member definition
    SELECT 
        CAST(ROW_NUMBER() OVER(ORDER BY o.myid) as decimal(38, 20)) as sort,
        o.parentid, 
        o.myid, 
        0 as level, 
        o.somedata
    FROM 
        table1 t1,
        table2 t1,
        datatable o
    WHERE t1.somebool = 1 AND t2.id = t1.foreignid and o.foreignkey = t2.key
        and o.parentid = ''
    UNION ALL
-- Recursive member definition
    SELECT
        CAST(b.sort + (ROW_NUMBER() OVER(ORDER BY o.myid) / power(10.0, b.level + 1)) as decimal(38, 20)) as sort,
        o.parentid, 
        o.myid, 
        b.level + 1, 
        o.somedata
    FROM datatable o
    INNER JOIN myCTE AS b
        ON o.parentid = b.myid

总体思路如下:从基于 table1 和 table2 的项目选择开始,我想启动查询并在锚点中找到所有没有父项的数据,将其与具有主要项目的数据连接起来和父母继续挖掘,直到我找到所有数据。我正在处理一棵深度未知的树,尽管我发现的最高级别是 7。

对递归成员应用额外限制是否有用?我从锚点复制的限制越多,它似乎工作得越好,但仅仅过滤“o.parentid = b.myid”就足够了吗?

4

1 回答 1

1

这是我推荐的调试/调整方法:

1)添加如下查询提示,排除无限循环的可能。

...
)
SELECT  parentid ,
        myid ,
        [level]
FROM myCTE 
OPTION (MAXRECURSION 20)

2) 如果返回结果,则尝试使用注释掉查询提示的相同查询。它应该在大约同一时间运行并返回相同数量的结果。

3)此时您应该添加回排序字段。除非有特定要求将其包含在递归中,否则我建议您将其移动到针对 CTE 的查询中,就像这样。

...
)
SELECT  parentid ,
        myid ,
        [level],
        -- I'm not sure what this accomplishes:
        -- ROW_NUMBER() OVER (ORDER BY CAST(myid) ASC) / CAST (POWER(10,level) AS DECIMAL(38,20)) AS sort
        -- Wouldn't this look nicer?
        ROW_NUMBER() OVER (ORDER BY [level] ASC, CAST ([parentid] AS INT) ASC, CAST ([myid] AS INT) ASC) AS sort

FROM myCTE 
ORDER BY [sort]
OPTION (MAXRECURSION 20)

3) 最后,添加回表 1 和表 2 上的联接。我鼓励您也将其添加到 CTE 查询中。

我知道您有一个解决方法,但如果您花时间看看我的方法是否适合您,我将不胜感激。

于 2014-07-24T19:35:34.283 回答