Sql server 2005 TSQL递归-表中具有双重值的最大递归错误

Sql server 2005 TSQL递归-表中具有双重值的最大递归错误,sql-server-2005,tsql,recursive-query,Sql Server 2005,Tsql,Recursive Query,相关问题: 我要问第二个关于递归的问题,因为这一次它是不同的(在我看来),所以请不要删除它 我有一个包含值的表: ORDER_ID Previous_STATUS_ID Next_STATUS_ID Create_Date 2 null 1 '2012-01-02' 2 1 2 '2012-01-03' 2

相关问题:

我要问第二个关于递归的问题,因为这一次它是不同的(在我看来),所以请不要删除它

我有一个包含值的表:

ORDER_ID   Previous_STATUS_ID   Next_STATUS_ID  Create_Date
2          null                 1               '2012-01-02'
2          1                    2               '2012-01-03'
2          2                    3               '2012-01-04'
2          3                    1               '2012-01-05'
3          1                    2               '2012-01-06'
2          2                    3               '2012-01-10'
2          3                    5               '2012-01-13'
2          5                    1               '2012-01-22'
2          1                    2               '2012-01-22'
这很好:

with change_tree as 
(
  SELECT order_id,
         previous_status_id, 
         next_status_id,
         cast(next_status_id as varchar(max)) as status_path
  FROM status_change
  WHERE previous_status_id = 5
    AND order_id = 2

  UNION ALL 

  SELECT sc.order_id,
         sc.previous_status_id,
         sc.next_status_id,
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max))
  FROM status_change sc 
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id
)
SELECT *
FROM change_tree
WHERE status_path = '5,1';
但如果我这样修改它:

with change_tree as 
(
  SELECT sc.order_id,
         sc.previous_status_id, 
         sc.next_status_id,
         cast(sc.next_status_id as varchar(max)) as status_path,
         sc.Create_Date as StartDate,
         sc.Create_Date as EndDate
  FROM status_change sc
  WHERE previous_status_id = 1
    AND order_id = 2

  UNION ALL 

  SELECT sc.order_id,
         sc.previous_status_id,
         sc.next_status_id,
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max))
         sc.Create_Date as StartDate,
         st.Create_Date as EndDate
  FROM status_change sc 
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id
)
SELECT *
FROM change_tree
WHERE status_path = '1,2,3';
我得到最大递归错误

这是我希望得到的数据:

ORDER_ID   StartDate        EndDate
2          '2012-01-02'     '2012-01-04' 
2          '2012-01-05'     '2012-01-10' 
这将作为报告进行。所以我想把结果存储在另一个表中,晚上只做那些新的或状态序列已经结束的订单

因此,在我的报告表中,我必须有这两条记录,在将下一条记录添加到status_change表之后,如下所示:

ORDER_ID   Previous_STATUS_ID   Next_STATUS_ID  Create_Date
2          2                    3               '2012-02-25'
我的过程(函数应仅添加到报告表的最后一个序列)。
希望您能理解我的观点:)

您在循环中被捕获,因为首先您选择了此行:

2          1                    2               '2012-01-22'
然后

然后

然后一次又一次地排第一行。您需要检查您的数据是否与您的报告足够一致

或者,您可能需要在CTE中添加以下条件:

ct.previous_status_id > sc.previous_status_id 
或者,您可以通过控制递归级别的addind参数更改脚本,如下所示:

with change_tree as  
( 
  SELECT sc.order_id, 
         sc.previous_status_id,  
         sc.next_status_id, 
         cast(sc.next_status_id as varchar(max)) as status_path, 
         sc.Create_Date as StartDate, 
         sc.Create_Date as EndDate,
         1 AS deep 
  FROM status_change sc 
  WHERE previous_status_id = 1 
    AND order_id = 2 

  UNION ALL  

  SELECT sc.order_id, 
         sc.previous_status_id, 
         sc.next_status_id, 
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max)) 
         sc.Create_Date as StartDate, 
         st.Create_Date as EndDate,
         ct.deep + 1 AS deep
  FROM status_change sc  
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id 
  WHERE deep < 3
) 
SELECT * 
FROM change_tree 
WHERE status_path = '1,2,3'; 

这正是我现在的处境。我来核对你的答案。还有一件事-如何以增量方式完成该报告?这样我的程序就不必每天晚上检查整个状态变更表了@安德烈·古里诺维奇认为,这可能是另一个问题的主题。但你为什么担心你的桌子会被完全重新加工呢?有这么大吗?处理需要很多时间吗?我有大约800k+行和大约30个模式要搜索(不同的状态和路径组合)。所以我认为,对每一行进行每一次组合都会给我带来大约2400万次操作。但订单仍然被添加到表中,我的模式数量也在增加。报告类型为“按需”,所以用户点击按钮,片刻后他应该会得到该报告。这就是为什么我认为聚合表是必要的。如果我错了,请纠正我:)@Andrey GurinovCan您的旧数据已更改?我的意思是,增量过程应该只向聚合表添加新记录,还是应该更新/删除旧记录?对于30种模式,我认为我建议的最后一个选项将是最有用的。您可以在CTE和外部选择中使用OR运算符组合不同的状态路径组合。
ct.previous_status_id > sc.previous_status_id 
with change_tree as  
( 
  SELECT sc.order_id, 
         sc.previous_status_id,  
         sc.next_status_id, 
         cast(sc.next_status_id as varchar(max)) as status_path, 
         sc.Create_Date as StartDate, 
         sc.Create_Date as EndDate,
         1 AS deep 
  FROM status_change sc 
  WHERE previous_status_id = 1 
    AND order_id = 2 

  UNION ALL  

  SELECT sc.order_id, 
         sc.previous_status_id, 
         sc.next_status_id, 
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max)) 
         sc.Create_Date as StartDate, 
         st.Create_Date as EndDate,
         ct.deep + 1 AS deep
  FROM status_change sc  
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id 
  WHERE deep < 3
) 
SELECT * 
FROM change_tree 
WHERE status_path = '1,2,3'; 
with change_tree as  
( 
  SELECT sc.order_id, 
         sc.previous_status_id,  
         sc.next_status_id, 
         cast(sc.next_status_id as varchar(max)) as status_path, 
         sc.Create_Date as StartDate, 
         sc.Create_Date as EndDate
  FROM status_change sc 
  WHERE previous_status_id = 1 
    AND order_id = 2 

  UNION ALL  

  SELECT sc.order_id, 
         sc.previous_status_id, 
         sc.next_status_id, 
         ct.status_path + ',' + cast(sc.next_status_id as varchar(max)) 
         sc.Create_Date as StartDate, 
         st.Create_Date as EndDate
  FROM status_change sc  
    JOIN change_tree ct ON ct.next_status_id = sc.previous_status_id AND ct.order_id = sc.order_id 
  WHERE 
     '1,2,3' LIKE ct.status_path + ',' + cast(sc.next_status_id as varchar(max)) + '%'
) 
SELECT * 
FROM change_tree 
WHERE status_path = '1,2,3';