Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

sql server 2008 - Recursive Child/Parent queries in T/SQL

I am using T/SQL in Microsoft SQL Server 2008

I have a table

CREATE TABLE [TestTable](
[CHILD] [int] NOT NULL,
[PARENT] [int] NOT NULL
) ON [PRIMARY]

GO

These are some values which define a parent child hierarchial relationship

CHILD PARENT
1       2
2       0
3       1
4       2
5       0

Visually, this table looks like this

0
   2
      1
         3
      4
   5

I would ideally like the values to be shown as follows (where the right hand column indicates the generation)

CHILD    GENERATION
 0          0
 2          1
 1          2
 3          3
 4          2
 5          1

My T/SQL code looks like this

with n(CHILD, PARENT, GENERATION) as (
select CHILD, PARENT,1 as GENERATION from TestTable
where PARENT=0 
union all
select nplus1.CHILD, nplus1.PARENT, GENERATION+1 from TestTable as nplus1, n
where nplus1.PARENT=n.CHILD 
)
select CHILD,GENERATION from n

However it doesn't work!

It returns

CHILD   GENERATION
2        1
5        1
1        2
4        2
3        3

It has the right generation, but the wrong sort order! Does anyone have any ideas how to solve this?

Thank you!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You'll need your recursion to also build something that can be sorted by at the end:

declare @t TABLE (
[CHILD] [int] NOT NULL,
[PARENT] [int] NOT NULL
) 

insert @t values
( 0, -1),   -- I added this
( 1, 2 ),
( 2, 0 ),
( 3, 1 ),
( 4, 2 ),
( 5, 0 )

(note I have added a true root element)

;with n(CHILD, PARENT, GENERATION, hierarchy) as (
select CHILD, PARENT,0, CAST(CHILD as nvarchar) as GENERATION from @t
where PARENT=-1
union all
select nplus1.CHILD, nplus1.PARENT, GENERATION+1, 
cast(n.hierarchy + '.' + CAST(nplus1.child as nvarchar) as nvarchar)
 from 
@t as nplus1 inner join n on nplus1.PARENT=n.CHILD 
)
select CHILD,GENERATION
from n
order by hierarchy

returns

CHILD       GENERATION
----------- -----------
0           0
2           1
1           2
3           3
4           2
5           1

Including the hierarchy for illustration:

CHILD       GENERATION  hierarchy
----------- ----------- ------------------------------
0           0           0
2           1           0.2
1           2           0.2.1
3           3           0.2.1.3
4           2           0.2.4
5           1           0.5

Depending on how big your ids get, you might have to do stuff with left-padding with zeroes to get the sorting right.

Note that SQL 2008 has a built-in hierarchy type for this kind of thing...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...