如何从表格中选择层次结构中的最低级别

4

我有一个带父子关系的表格:

Table A
Column Id int
Column Parent_Id int
Column Description text

一个数据集的示例如下:
999, NULL, 'Corp.'
998, 999, 'Div1',
997, 999, 'Div2', 
510, 998, 'Child Div1A',
110, 997, 'Child Div2A',
120, 997, 'Child Div2B',

我的查询需要返回给定父级最低层次的子级。因此,例如,如果给定999,则我将返回510、110、120。但是如果给定997,则我只会返回110和120。如果给定110,则不会返回任何内容。我无法正确格式化我的查询。我通过在表格上进行自连接来开始,但似乎这只能让我降到1个层级,而实际上我需要下降N个层级。


对于 SQL Server 中的递归下降,您需要使用 CTE - SWeko
2个回答

5
Declare @t Table(ID int,Parent_ID int,Description varchar(20))

insert into @t values(999, NULL, 'Corp.')
insert into @t values(998, 999, 'Div1')
insert into @t values(997, 999, 'Div2')
insert into @t values(510, 998, 'Child Div1A')
insert into @t values(110, 997, 'Child Div2A')
insert into @t values(120, 997, 'Child Div2B')

;WITH Rollups AS (
    SELECT Id, Parent_Id, Description 
    FROM @t WHERE ID = 999
    UNION ALL
    SELECT parent.Id, parent.Parent_Id, child.Description
    FROM @t parent 
    INNER JOIN Rollups child ON child.Id = parent.Parent_Id
)
SELECT *
FROM Rollups
Where not Exists(Select * from @t where Parent_Id=Rollups.ID) 

@bummi 你是一位巨星!!传奇的回答! - aMazing

3

我没有测试过这个,但我认为这就是你需要的——使用带有 UNIONCTE(我从一个我使用的更复杂的示例中削减了它):

;WITH CTE (ChildID, [Text], ParentID)
AS
(
    SELECT ChildID, [Text], ParentID
    FROM Table1
    WHERE ParentId IS NULL --or = @ParentID
    UNION ALL
    SELECT T1.ChildID, T1.[Text], T1.ParentID
    FROM Table1 AS T1
    INNER JOIN CTE
    ON T1.ParentID = CTE.ChildID
)
SELECT ChildID, [Text]
FROM CTE

这很不错(谢谢!),但有一种情况它不起作用...如果我将条件从“ParentId IS NULL”切换到“ParentId = @ParentID”,则不起作用的情况是当@ParentID是最高级别时。它会返回直接子级,而应该仅返回最低级别。@bummi下面的答案添加了另一个条件来解决这个问题。感谢您的帮助。 - Thelonias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接