2012-08-24 53 views
3

選擇孩子我有這樣從無限層次

ID | ParentID 
1  | null 
2  | null 
3  | null 
4  | 1 
5  | 4 
6  | 5 
7  | 6 
8  | 7 
9  | 8 

SQL表現在,你可以看到,孩子父母關係得以維持。我想要一個查詢來選擇給定ID的「所有級別」的孩子。

假設,如果我輸入ID = 1,結果應該是

ID | ParentID 
1  | null 
4  | 1 
5  | 4 
6  | 5 
7  | 6 
8  | 7 
9  | 8 

所以所有的直接孩子,以及他們的孩子的孩子在任何級別的,應該拿出。

MS SQL服務器中可以這樣做嗎?我有MS-SQL server 2012.

+0

http://stackoverflow.com/questions/207309/sql-query-for-parent-child-relationship – Sajith

回答

3

這裏遞歸過程是一個額外的字段名稱的例子,但與CTE的遞歸簡單:

DECLARE @ID int 

SET @ID = 1; 

WITH CTE_Table_1 
(
    ID, 
    Name, 
    ParentID, 
    TreeLevel 
) 
AS(
SELECT 
    ID, 
    Name, 
    ParentID, 
    0 AS TreeLevel 
FROM Table_1 
WHERE ID = @ID 

UNION ALL 

SELECT 
    T.ID, 
    T.Name, 
    T.ParentID, 
    TreeLevel + 1 
FROM Table_1 T 
INNER JOIN CTE_Table_1 ON CTE_Table_1.ID = T.ParentID 
) 

SELECT * FROM CTE_Table_1 
0

從SQL Server 2005中,Common Table Expressions已被添加到SQL Server的T-SQL中,可以幫助您處理這類層次查詢。這就是你正在尋找的!

+0

是的,這可以幫助我,但不知道如何工作,請提供一些例子。 – yogi

+0

安德拉斯爲此給了CTE,我認爲你很好走。 – Vikdor

1

試試這個幹活罰款:http://www.sqlteam.com/Forums/topic.asp?TOPIC_ID=101053

-- Structure 
create table dbo.MyPeople (Id int, Name varchar(30), ParentId int) 

-- Data 
insert dbo.MyPeople 
      select 1, 'P1', null 
union all select 2, 'P2', null 
union all select 3, 'P1C1', 1 
union all select 4, 'P1C2', 1 
union all select 5, 'P2C1', 2 
union all select 6, 'P1C2C1', 4 
union all select 7, 'P1C1C1', 3 
union all select 8, 'P1C1C1C1', 7 
union all select 9, 'P2C1C1', 5 
union all select 10, 'P1C3', 1 
go 

-- Function 
create function dbo.AncestorPath(@Id int) returns varchar(100) as 
begin 
    declare @Path varchar(100) 
    while 0 = 0 
    begin 
     select @Path = cast(Id as varchar(5)) + isnull('/' + @Path, ''), @Id = ParentId 
     from dbo.MyPeople where Id = @Id 

     if @@rowcount = 0 break 
    end 

    return @Path 
end 
go 

-- Calculation 
select * from (
    select *, dbo.AncestorPath(Id) as AncestorPath from dbo.MyPeople) a 
where '/' + AncestorPath + '/' like '%/1/%' 

嘗試這樣

ALTER PROCEDURE dbo.GetChildren 
@ParentId int 

AS 

SET NOCOUNT ON 

SELECT * 
FROM MainTable 
WHERE ChildId IN 
(
SELECT ParentId 
FROM f_GetChildren(@ParentId) 
UNION 
SELECT ChildId 
FROM f_GetChildren(@ParentId) 
) 
ORDER BY ParentId 

SET NOCOUNT OFF 
RETURN