私のCTEは特定の顧客に対して無限ループで実行され、その理由を見つけることができません。
これがクエリです:
;WITH ClassTree
AS (SELECT ID, NAME, Parent_ID
FROM TableName
WHERE ID = 1
UNION ALL
SELECT T.ID, T.NAME, T.Parent_ID
FROM TableName T WITH (NOLOCK)
JOIN ClassTree
ON Parent_ID = ClassTree.ID
)
SELECT * FROM ClassTree
これで問題の記録が見つかると思います。 LEVEL
を階層に追加し、複数のレベルに存在する個々のIDレコードを探します。
;WITH ClassTree
AS (SELECT ID, NAME, Parent_ID, 1 as 'Level'
FROM TableName
WHERE ID = 1
UNION ALL
SELECT T.ID, T.NAME, T.Parent_ID, Level + 1 as 'Level'
FROM TableName T WITH (NOLOCK)
JOIN ClassTree
ON Parent_ID = ClassTree.ID
)
SELECT *
FROM ClassTree c1
WHERE EXISTS (SELECT 1 FROM ClassTree c2
WHERE c2.id = c1.id
AND c2.Level > c1.level)
ここにあなたのサイクルを見つけるために使用できる小さなものがあります。
declare @T table
(
ID int,
Parent_ID int
)
insert into @T values
(1, 3),(2, 1),(3, 2), -- This is a cycle
(4, 4), -- This is a cycle
(5, null),(6, 5),(7, 6) -- This is not a cycle
;with C as
(
select T.ID,
T.Parent_ID,
cast(',' + cast(ID as varchar(10)) + ',' as varchar(max)) as Path,
0 Cycle
from @T as T
union all
select T.ID,
T.Parent_ID,
C.Path + cast(T.ID as varchar(10)) + ',',
case when C.Path like '%,'+cast(T.ID as varchar(10))+',%'
then 1
else 0
end
from @T as T
inner join C
on T.Parent_ID = C.ID
where C.Cycle = 0
)
select *
from C
where Cycle = 1
結果:
ID Parent_ID Path Cycle
----------- ----------- ---------- -----------
4 4 ,4,4, 1
3 2 ,3,1,2,3, 1
2 1 ,2,3,1,2, 1
1 3 ,1,2,3,1, 1
私が最初にすることはこれを変更することです:
JOIN ClassTree
ON Parent_ID = ClassTree.ID
これに:
JOIN ClassTree
ON t.Parent_ID = ClassTree.ID
結合でテーブルエイリアスを指定しなかったため、ClassTreeをそれ自体に結合しようとしている可能性があります。