需要在存储过程中获取后代项列表

时间:2011-11-09 17:25:50

标签: sql sql-server-2008 tsql stored-procedures hierarchy

说明

有两个列(ParentId和ChildId)组成的表,显示某些实体的层次结构。每个Id只能在ParentId列中显示一次。这意味着每个实体只有一个子实体。

问题: 我需要检查实体(其ID)是否在父实体的后代列表中。

2 个答案:

答案 0 :(得分:2)

DECLARE @parentId INT
DECLARE @childId INT
DECLARE @targetChildId INT
SET @targetChildId=<put id of a child you want to find>
SET @parentId=<put id of a parent you are looking child for>
SET @childId=0

WHILE (@childId<>@targetChildId)
    BEGIN
        IF(EXISTS(SELECT ChildId FROM Hierarchies WHERE ParentId=@parentId))
        BEGIN
            SET @childId=(SELECT ChildId FROM Hierarchies WHERE ParentId=@parentId)
            SET @parentId=@childId
        END 
        ELSE
        BEGIN
            SET @childId=0
            BREAK
        END
    END
PRINT @childId

如果在目标父母中找不到目标孩子,则返回0。

答案 1 :(得分:1)

示例数据:

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])

我正在使用recursive CTE列出后代。最后一个后代的要么创建一个循环,要么不创建。