Understanding the recursive CTE termination check

前端 未结 1 1683
梦谈多话
梦谈多话 2021-01-23 09:12

In this sqlfiddle...

http://sqlfiddle.com/#!6/b6587/6

I am getting the following error....

The statement terminated. The maximum recursion

1条回答
  •  抹茶落季
    2021-01-23 09:39

    Here's a better example using dates. Assume we want to build a table of dates. 1 row for every month for the year 2017. We create a @startDate as the anchor and @endDate as the terminator. We set these to 12 months apart, since we want a single year. Then, the recursion will add one month via the DATEADD function to the @startDate until the terminator is met in the WHERE clause. We know it will take 11 recursions to hit 12 months... that is, 11 months + the start date. If we set the MAXRECURSION to anything less than 11, then it will fail since 11 are needed to fulfill the WHEREclause in our recursive CTE, that is the terminator..

    declare @startDate datetime = '20170101'
    declare @endDate datetime = '20171201'
    
    ;WITH Months
    as
    (
        SELECT @startDate as TheDate       --anchor
        UNION ALL
        SELECT DATEADD(month, 1, TheDate)  --recursive
        FROM Months
        WHERE TheDate < @endDate           --terminator... i.e. continue until this condition is met
    
    )
    
    
    SELECT * FROM Months OPTION (MAXRECURSION 10) --change this to 11
    

    For your query, a simple join would suffice.

    select 
      firstName
      ,lastName
      ,orderDate
      ,productID
    from
      customers c
    inner join
      orders o on o.customerID = c.id
    

    However, I see that you are trying to return this in an odd format, which should be handled in what ever reporting application you are using. This would get you close without recursion.

    with cte as(
    select 
      firstName
      ,lastName
      ,orderDate
      ,productID
      ,dense_rank() over(order by c.id) as RN
    from
      customers c
    inner join
      orders o on o.customerID = c.id)
    
    
    select distinct
      firstName
      ,lastName
      ,null
      ,null
      ,RN
    from 
      cte
    union all
    select
      ''
      ,''
      ,orderDate
      ,productID
      ,RN
    from 
      cte
    order by RN, firstName desc
    

    0 讨论(0)
提交回复
热议问题