【问题标题】:Multiple recursive union all selects in a CTE SQL queryCTE SQL查询中的多个递归联合所有选择
【发布时间】:2015-12-02 15:31:07
【问题描述】:

我正在尝试构建一个查询,以使用 CTE 查询从表中搜索所有父行和子行。

我可以搜索父母并返回孩子,也可以搜索孩子并返回父母,但我无法在一个查询中处理这两种可能性。

我只能完成一个 UNION ALL 查询。

我哪里错了?

declare @search nvarchar(50)

--set @search = '%Nucleus sub project%';
set @search = '%Nucleus test';

WITH Parent AS
(
    SELECT * 
    FROM tblProjects 
    WHERE ProjNo LIKE @search 
       OR ProjDes LIKE @search

    UNION ALL

    SELECT tblProjects.* 
    FROM tblProjects  
    JOIN Parent ON tblProjects.proID = Parent.ParentProjID

    UNION ALL

    SELECT tblProjects.* 
    FROM tblProjects  
    JOIN Parent ON tblProjects.ParentProjID = Parent.proID 
)
SELECT distinct * 
FROM Parent 
ORDER BY ParentProjID

我得到一个错误:

语句终止。在语句完成之前,最大递归 100 已用完。

【问题讨论】:

  • 您遇到的错误是什么?
  • The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
  • 您一遍又一遍地选择所有行的组合 - 这是一个无限循环,基本上(仅使用递归)。如果您想要后代和祖先,请为后代创建一个with,为祖先创建另一个,然后为这两个创建union all :)

标签: sql-server tsql common-table-expression


【解决方案1】:

尝试使用两种不同的 CTE:

WITH x AS (
    SELECT p.*
    FROM tblProjects p
    WHERE  ProjNo LIKE @search OR ProjDes LIKE @search
   ),
   parents as (
    SELECT * 
    FROM x 
    UNION ALL
    SELECT p.* 
    FROM parents JOIN
         tblProjects p
         ON p.parentid= parents.proID
   ),
   children as (
    SELECT * 
    FROM x 
    UNION ALL
    SELECT p.* 
    FROM children JOIN
         tblProjects p
         ON children.parentid = p.proID
   )
SELECT distinct * 
FROM parents
UNION
SELECT distinct *
FROM children;

【讨论】:

    【解决方案2】:

    递归调用 UNION ALL 之后的第二个选择,直到没有更多的行添加到结果集中。

    所以;

    1. 您不需要第三个 SELECT 语句。第二个应该可以捕获所有内容。
    2. 如果您有循环(例如,A 的父项是 B;B 的父项是 A),您将获得无限递归,并且 SQL 将在 100 次迭代后退出,从而为您提供最大递归错误。

    检测周期更复杂,但可以做到。

    【讨论】:

      猜你喜欢
      • 2016-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-15
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      相关资源
      最近更新 更多