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

时间:2012-12-21 14:50:47

标签: sql sql-server

我有一个父/子关系表:

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,则不会返回任何内容。我无法弄清楚如何正确地格式化我的查询。我开始加入桌子本身,但似乎只有当我真正需要降低N级时才能让我降低1级。

2 个答案:

答案 0 :(得分: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) 

答案 1 :(得分:3)

我没有对此进行过测试,但我认为这是您需要的 - 使用CTE UNION(我已经从我使用的更复杂的示例中删除了它):

;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