如何连接两个等效表,它们是 SQL Server 中先前递归选择的结果

Posted

技术标签:

【中文标题】如何连接两个等效表,它们是 SQL Server 中先前递归选择的结果【英文标题】:How to join two equivalent tables which are the result of the previous recursive select in SQL Server 【发布时间】:2013-05-10 12:21:44 【问题描述】:

大家好!首先,我为我糟糕的英语感到抱歉。好吧,我有一个问题,您可以在此消息的标题中阅读。

当我尝试选择必要的数据时,SQL Server 返回此消息(错误 253)。

翻译“来自 CTE 的递归元素(名称为 'recurse' - my 注意)在 CTE 中有多个引用。

我该如何解决这个问题?

你能建议我如何连接两个表(有 2 列(例如:a 和 b),它们是先前递归选择的结果(我正在写相同的选择,但关于 if 的另一个迭代)

    with recurse (who_acts,on_whom_influence)
as 
(
-------------------------------------------FIRST SELECT
select  distinct interface_1.robot_name as who_acts,interface_2.robot_name as on_whom_influence
from INTERFACE as interface_1,INTERFACE as interface_2
    where (interface_1.number in (                                  select  INPUT_INTERFACE.source
                                        from INPUT_INTERFACE
                                )
            and interface_2.number in (
                                        select INPUT_INTERFACE.number 
                                        from INPUT_INTERFACE
                                        where (INPUT_INTERFACE.source=interface_1.number )
                                     )
          )

-------------------------------------------RECURSIVE PART   
union all
select rec1.who_acts,rec1.on_whom_influence
from recurse as rec1
inner join 
(select rec2.who_acts,rec2.on_whom_influence
from recurse as rec2) as P on (1=1)
)
select  * from recurse

问题出在recurse CTE。连接条件不简单,但没有 对这个问题的影响。 你能在 cmets 中输入一些工作代码吗

【问题讨论】:

您能否向我们展示有问题的查询,并解释所涉及的表及其结构? 我刚刚添加了它。也许这段代码不起作用,但我不能全部编写代码并调试它。 第一个选择返回我正确的数据集,MS SQL 在第二部分发誓 您能否在问题中添加一些示例输入数据及其预期输出?就目前而言,您的查询似乎根本不需要 recursive 查询。 您不必总是在一个查询中解决问题。临时表和查询批处理在 (1) 可维护性 (2) 查询计划稳健性 (3) 可优化性方面工作得更好,例如临时表上的集群 【参考方案1】:

这是一张假表

create table tbl1 ( a int, b int );
insert tbl1 select 1,2;
insert tbl1 select 11,12;
insert tbl1 select 2,3;
insert tbl1 select 4,5;

还有一个与你类似的查询

with cte as (
  select a,b from tbl1
  union all
  select x.a,x.b from cte x join cte y on x.a=y.a+1
)
select * from cte;

错误:

公用表表达式“cte”的递归成员具有多个递归引用。: with cte as (select a,b from tbl1 union all select x.a,x.b from cte x join cte y on x.a=y.a+1)从 cte 中选择 *

基本上,错误正是它所说的。在递归部分中,递归 CTE 的出现次数不能超过 ONCE。在上面,您看到CTE 别名为xy。这种限制有多种原因,例如 CTE 是递归的 depth-first 而不是逐代递归的。


应该考虑的是为什么您会多次需要它。您的递归部分没有意义。

select rec1.who_acts,rec1.on_whom_influence
from recurse as rec1
inner join 
(   select rec2.who_acts,rec2.on_whom_influence
    from recurse as rec2) as P on (1=1)

从表面上看,如果recurse 是一个真实的表(非 CTE),则以下情况是正确的:

    生成的行数为count(recurse as [rec1]) x count(recurse as [rec2])。 递归 (rec1) 中的行在递归中每行都被复制,因此 #1 从不使用 rec2 中的列。 rec2 仅用于乘法

如果允许运行,查询的递归部分将保持二次增加其行数并且永远不会完成。

【讨论】:

我尝试在您的消息中发布来自 2 个第一个代码块的代码。好吧,SQL 服务器对你的代码发誓。 SQL 返回“同样的错误” “如果允许运行,查询的递归部分将保持二次增加其行数并且永远不会完成。”是的,但是我有一个算法,但是如果没有这一步,sql 约束不能让我在 sql 中实现它 这正是我在下一句中所声称的。 “错误:......”随后是解释。这根本是不允许的,我还没有要求这样的语法。 YES, but I've got an algorithm but sql constraints cant allow me do it ?所以你有一个算法来生成无限数量的行,而 SQL Server 不允许你这样做 - 这是一个问题吗? 好的。如果我可以使用 CTE 超过 1 次。如果我可以加入这 2 个 CTE ......当前一个选择返回与当前相同的行数时,我的算法递归选择停止

以上是关于如何连接两个等效表,它们是 SQL Server 中先前递归选择的结果的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET + SQL SERVER + JSON = 如何在 SQL Server 的两个连接表中获取数据并加载为 JSON?

SQL Server:删除表级联等效?

如何轻松连接表 Microsoft SQL Server?

如何将两个表与 SQL Server 中第二个表中引用同一列的两列连接起来

如何在 SQL Server 中同时连接两个数据库?

SQL Server 2005 排序规则问题