jdi*_*ids 1 sql-server t-sql sql-server-2012
正如标题所述,我有一个递归 CTE,当我更改 WHERE 子句中的运算符时,即使只有两行数据,它也会爆炸。
CREATE TABLE #Recursion
(Parent varchar(10), Child varchar(10), TopDate datetime)
INSERT INTO #Recursion (Parent, Child, TopDate)
VALUES
('00003137', '00003137', '2018-08-31'),
('04536347', '00003137', '2017-02-28'),
('05458040', '05458040', '9999-12-31'),
('00269705',' 05458040',' 9999-12-31')
;WITH
Parent AS
( SELECT parent
, child
, 1 as sort
, TopDate
FROM #Recursion
WHERE parent = child
UNION ALL
SELECT s.parent
, d.child
, d.sort + 1
, s.TopDate
FROM Parent as d
JOIN #Recursion s
ON s.child= d.parent
WHERE s.TopDate < d.TopDate
)
SELECT parent
, child
, sort
FROM Parent
ORDER BY parent, sort desc
OPTION (maxrecursion 0);
DROP TABLE #Recursion
Run Code Online (Sandbox Code Playgroud)
如果我保留 where 子句,它会起作用
WHERE s.TopDate < d.TopDate
Run Code Online (Sandbox Code Playgroud)
一旦我将其更改为这个,它就会爆炸并且不会完成
WHERE s.TopDate <= d.TopDate
Run Code Online (Sandbox Code Playgroud)
如果日期小于或等于,我确实需要运行一些测试。为什么这行不通,即使只有两行数据?
这是一些示例数据。请注意日期字段如何相同
parent child sort TopDate
00003137 04536347 2 2017-02-28
00003137 00003137 1 2018-08-31
00269705 00269705 2 9999-12-31
00269705 05458040 1 9999-12-31
Run Code Online (Sandbox Code Playgroud)
除了具有相同 TopDates 的数据外,我可以让它处理所有数据
如果您将根节点建模为具有 parent=child,则必须将它们从递归子句中排除,否则您将获得无限循环。您s.TopDate < d.TopDate
目前是查询中唯一防止无限循环的东西。
EG,如果更改<
到<=
查询将进入一个无限循环。请注意,这(maxrecursion 0)
可能不是一个好主意。
drop table if exists #Recursion
go
create table #Recursion(parent int, child int, topdate datetime)
go
insert into #Recursion(parent,child,topdate) values (1,1,getdate());
;WITH
Parent AS
( SELECT parent
, child
, 1 as [order]
, TopDate
FROM #Recursion
WHERE parent = child
UNION ALL
SELECT s.parent
, d.child
, d.[order] + 1
, s.TopDate
FROM Parent as d
JOIN #Recursion s
ON s.child = d.parent
WHERE s.TopDate < d.TopDate
)
SELECT parent
, child
, [order]
FROM Parent
ORDER BY parent, [order] desc
OPTION (maxrecursion 0);
Run Code Online (Sandbox Code Playgroud)
还
ON s.child = d.parent
Run Code Online (Sandbox Code Playgroud)
应该是
ON d.child = s.parent
Run Code Online (Sandbox Code Playgroud)
由于您似乎是从根节点开始,因此您需要通过 UNION ALL 行向下递归,这些行parent
是前一次迭代的child
.