如何连接两个等效表,它们是 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
别名为x
和y
。这种限制有多种原因,例如 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?