sql - 如何将递归 CTE 转换为可在 SQL Server 2000 中使用

标签 sql sql-server recursion

我有一个像这样的递归 CTE 查询:

;WITH    cte
      AS ( SELECT   e.entryID ,
                    e.bOpen ,
                    e.nextEntryID ,
                    e.entryID AS OriginalentryID
           FROM     entries e
           WHERE    e.bOpen = 1
                    AND e.nextEntryID IS NOT NULL

           UNION ALL

           SELECT   e.entryID ,
                    e.bOpen ,
                    e.nextEntryID ,
                    c.OriginalentryID
           FROM     cte c
                    INNER JOIN entries e ON e.entryID = c.nextEntryID
         )
SELECT  c.entryID ,
        c.OriginalentryID
FROM    cte c
WHERE   bOpen = 0;


有没有办法在没有 CTE 的情况下实现这一点(即对于 SQL Server 2000)?
任何提示/想法都会受到赞赏。

最佳答案

对于 SQL 2000,您可以创建一个模拟 CTE 表达式的表函数,使用临时表和 WHILE 循环来加载它。

主要缺点是,在从函数返回之前应用 WHERE 约束不会使您受益,但如果层次结构表很小,它就可以工作。要减少在应用 WHERE 子句之前读取的数据量,您可以将参数传递给过滤器(请参阅代码注释):

CREATE FUNCTION dbo.FnGetEntriesByRoot (@rootId AS BIGINT)
RETURNS @result TABLE (
  entryID           BIGINT PRIMARY KEY,
  bOpen             BIT,
  nextEntryID       BIGINT,
  OriginalentryID   BIGINT
)
AS BEGIN

  -- insert the "root" element
  INSERT @result(entryID, bOpen, nextEntryID, OriginalentryID)
  SELECT e.entryID, e.bOpen, e.nextEntryID, e.entryID
  FROM entries e
  WHERE e.bOpen = 1
  AND (e.entryID = @rootId OR @rootId IS NULL) -- (1) filter condition!
  AND e.nextEntryID IS NOT NULL;

  -- while new items are found, insert into the result table
  WHILE (@@ROWCOUNT > 0) BEGIN
    INSERT @result(entryID, bOpen, nextEntryID, OriginalentryID)
    SELECT e.entryID, e.bOpen, e.nextEntryID, c.OriginalentryID
    FROM @result  c
    JOIN entries  e ON (e.entryID = c.nextEntryID)
    WHERE e.entryID NOT IN (SELECT entryID FROM @result)
  END

  RETURN;
END;

SELECT c.entryID, c.OriginalentryID
FROM dbo.FnGetEntriesByRoot(NULL) c
WHERE c.bOpen = 0;

关于sql - 如何将递归 CTE 转换为可在 SQL Server 2000 中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21990957/

相关文章:

sql - SQL Server 中的多元线性回归函数

java - 按顺序检索二叉搜索树中的元素

c++ - 使用递归解决 C++ 中的迷宫问题?

c - 为什么 stackoverflow 错误乱七八糟?

php - 调试 sql 查询如果失败

c# - 是否可以将非主键设置为另一个表中的外键?

sql - SQL Server 中对大型数据集的不同查询速度缓慢

sql-server - 启用 SYSTEM_VERSIONING 错误 - 历史表中的重叠日期

mysql - 给定一个用户,选择具有最常见评分的用户

sql - 如何在 MySQL 中对两个结果集中的列求和