为递归CTE获取1个以上的结果集?

Roy*_*mir 4 sql-server common-table-expression

我有一个简单的表,有叶子和子叶信息.(像论坛问题)

主要消息被定义,其中childIdParentID是相同的

在此输入图像描述

所以在这里我们看到2个主要问题及其答案.

我还设法计算每个元素的深度:

在此输入图像描述

简而言之,这是主要的查询:

    WITH CTE AS
    (
       SELECT childID
             ,parentID,
             0 AS depth,name
       FROM   @myTable
       WHERE   childID = parentID AND childID=1 -- problem line

       UNION ALL

       SELECT TBL.childID
             ,TBL.parentID,
              CTE.depth + 1 , TBL.name 
       FROM   @myTable AS TBL
               INNER JOIN CTE  ON  TBL.parentID = CTE.childID
       WHERE   TBL.childID<>TBL.parentID
    )
    SELECT childID,parentID,REPLICATE('----', depth) + name        
Run Code Online (Sandbox Code Playgroud)

但问题是第8行(评论).

我目前问"为问题ID#1提供所有群集"

那问题出在哪里?

我想为每个问题设置多个结果集!

所以这里我需要有2个结果集:

一对一childId=parentId=1 和一对一childId=parentId=6

完全工作的SQL在线

(我不想使用光标)

Mik*_*son 9

您可以动态构建查询.

DECLARE @SQL NVARCHAR(MAX) =
(SELECT '
WITH CTE AS
(
   SELECT childID
         ,parentID,
         0 AS depth,name
   FROM   myTable
   WHERE   childID = parentID AND childID = '+CAST(childID AS NVARCHAR(10))+'

   UNION ALL

   SELECT TBL.childID
         ,TBL.parentID,
          CTE.depth + 1 , TBL.name 
   FROM   myTable AS TBL
           INNER JOIN CTE  ON  TBL.parentID = CTE.childID
   WHERE   TBL.childID<>TBL.parentID
)
SELECT childID,parentID,REPLICATE(''----'', depth) + name
FROM   CTE   
ORDER BY
      childID;'

FROM  myTable
WHERE childID = parentID
FOR XML PATH(''), TYPE).value('text()[1]', 'NVARCHAR(MAX)');

EXEC sp_executesql @SQL;
Run Code Online (Sandbox Code Playgroud)

更新:

正如Bogdan Sahlean所建议的那样,我们可以通过参数化实际查询来最小化编译.

DECLARE @SQL1 NVARCHAR(MAX) =
'WITH CTE AS
(
   SELECT childID
         ,parentID,
         0 AS depth,name
   FROM   myTable
   WHERE   childID = parentID AND childID = @childID

   UNION ALL

   SELECT TBL.childID
         ,TBL.parentID,
          CTE.depth + 1 , TBL.name 
   FROM   myTable AS TBL
           INNER JOIN CTE  ON  TBL.parentID = CTE.childID
   WHERE   TBL.childID<>TBL.parentID
)
SELECT childID,parentID,REPLICATE(''----'', depth) + name
FROM   CTE   
ORDER BY
      childID;'

DECLARE @SQL2 NVARCHAR(MAX) =
(SELECT 'exec sp_executesql @SQL, N''@childID int'', '+CAST(childID AS NVARCHAR(10))+';'
FROM  myTable
WHERE childID = parentID
FOR XML PATH(''), TYPE).value('text()[1]', 'NVARCHAR(MAX)');

EXEC sp_executesql @SQL2, N'@SQL NVARCHAR(MAX)', @SQL1;
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于表变量. (4认同)

Aar*_*and 8

要向客户端提供多个结果集,您将不得不使用游标或while循环来执行独立SELECT操作.您无法从CTE执行此操作,因为CTE只能由一个后续查询使用.

现在,问题的根源与游标无关,但事实上你正在使用HTML转发器.为什么需要为此使用HTML转发器?一个简单的DataReader可以遍历CTE 单集的所有结果,并根据循环做出条件格式化决策,并确定根ID的变化.因此,我建议您尝试以不同的方式解决表示问题,而不是试图强制SQL Server来适应您的表示实现.

  • @RoyiNamir我看到了图像,但我无法理解你如何用一个结果集生成该表示.您只需要在客户端代码中使用更多逻辑来生成必要的HTML,并且它可能比使用`n`HTML转发器更有效. (2认同)