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!
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...
Based on AakashM's solution I'm proposing a solution that will be a bit more general, because it is using row_number to build the hierarchy
instead of using the column values.
Here is it:
;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(hierarchy + '.' + CAST(cast(ROW_NUMBER() over (order by nplus1.CHILD) as int) as nvarchar) as nvarchar)
from
@t as nplus1 inner join n on nplus1.PARENT=n.CHILD
)
select CHILD,GENERATION,hierarchy
from n
order by hierarchy
returns:
CHILD GENERATION hierarchy
0 0 0
2 1 0.1
1 2 0.1.1
3 3 0.1.1.1
4 2 0.1.2
5 1 0.2