我有一个这样的递归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),是否有任何方法可以实现这一点?
任何提示/想法都表示赞赏。
答案 0 :(得分:2)
对于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;