Пример данных:
CREATE TABLE [dbo].[EntityHierarchy]
(
[EntityId] INT,
[ChildEntityId] INT
)
INSERT [dbo].[EntityHierarchy]
VALUES (1, 2),
(2, 3),
(3, 4),
(4, 1) -- Cycle
Найти круговые отношения:
DECLARE @SearchEntityId INT = 1
;WITH [cteRursive] AS
(
SELECT 1 AS [ROW_NUMBER],
[ChildEntityId] AS [EntityId]
FROM [dbo].[EntityHierarchy]
WHERE [EntityId] = @SearchEntityId
UNION ALL
SELECT r.[ROW_NUMBER] + 1,
h.[ChildEntityId]
FROM [cteRursive] r
INNER JOIN [dbo].[EntityHierarchy] h
ON r.[EntityId] = h.[EntityId]
WHERE h.[ChildEntityId] <> @SearchEntityId
)
SELECT h.*
FROM [cteRursive] r
INNER JOIN [dbo].[EntityHierarchy] h
ON r.[EntityId] = h.[EntityId]
WHERE r.[ROW_NUMBER] = (SELECT MAX([ROW_NUMBER]) FROM [cteRursive])
Я использую рекурсивный CTE , чтобы перечислить потомков. дочерний элемент последнего потомка либо создает цикл, либо нет.