How does a Recursive CTE run, line by line?

后端 未结 5 1979
情书的邮戳
情书的邮戳 2020-11-27 12:33

I think I\'ve got the format of Recursive CTEs down well enough to write one, but still find myself frustrated to no end that I cannot manually process one (pretend to be th

5条回答
  •  佛祖请我去吃肉
    2020-11-27 13:10

    Think of a recursive CTE as of an endless UNION ALL:

    WITH    rows AS
            (
            SELECT  *
            FROM    mytable
            WHERE   anchor_condition
            ),
            rows2 AS
            (
            SELECT  *
            FROM    set_operation(mytable, rows)
            ),
            rows3 AS
            (
            SELECT  *
            FROM    set_operation(mytable, rows2)
            ),
            …
    SELECT  *
    FROM    rows
    UNION ALL
    SELECT  *
    FROM    rows2
    UNION ALL
    SELECT  *
    FROM    rows3
    UNION ALL
    …
    

    In your case, that would be:

    WITH    abcd1 AS
            ( 
            SELECT  *
            FROM    @tbl t
            WHERE   ParentId IS NULL 
            ),
            abcd2 AS
            ( 
            SELECT  t.*
            FROM    abcd1
            JOIN    @tbl t
            ON      t.ParentID = abcd1.id
            ),
            abcd3 AS
            ( 
            SELECT  t.*
            FROM    abcd2
            JOIN    @tbl t
            ON      t.ParentID = abcd2.id
            ),
            abcd4 AS
            ( 
            SELECT  t.*
            FROM    abcd3
            JOIN    @tbl t
            ON      t.ParentID = abcd3.id
            ),
            abcd5 AS
            ( 
            SELECT  t.*
            FROM    abcd4
            JOIN    @tbl t
            ON      t.ParentID = abcd4.id
            ),
            abcd6 AS
            ( 
            SELECT  t.*
            FROM    abcd5
            JOIN    @tbl t
            ON      t.ParentID = abcd5.id
            )
    SELECT  *
    FROM    abcd1
    UNION ALL
    SELECT  *
    FROM    abcd2
    UNION ALL
    SELECT  *
    FROM    abcd3
    UNION ALL
    SELECT  *
    FROM    abcd4
    UNION ALL
    SELECT  *
    FROM    abcd5
    UNION ALL
    SELECT  *
    FROM    abcd6
    

    Since abcd6 yields no results, this implies a stopping condition.

    Theoretically, a recursive CTE can be infinite, but practically, SQL Server tries to forbid the queries that would lead to infinite recordsets.

    You may want to read this article:

    • SQL Server: are the recursive CTE’s really set-based?

提交回复
热议问题