2
id  parent_id
1   0
2   0
3   2
4   0
5   1
6   0

I need a query that will return parent rows (parent_id=0) followed by its child rows:

  1. first parent
  2. all children of first parent
  3. second parent
  4. all children of second parent
  5. third parent
  6. fourth parent

Expected result: ordered by id

id   parent_id
-------------------------------------------
1    0 (first parent)
5    1     (all children of first parent)
2    0 second parent
3    2     (all children of second parent)
4    0 third parent
6    0 fourth parent

I can use union of parents followed by all childs But that gives me parents first then the children. I need parent and immediately its children.

Anyone can help?

0

2 Answers 2

3

If you're in SQL Server 2005+, you can use a recursive CTE, making sure that you maintain a field that you can order by at the end.

Try this:

declare @t table (id int, parent_id int)
insert @t
select 1,0
union all select 2,0
union all select 3,2
union all select 4,0
union all select 5,1
union all select 6,0
;

with tree as (
select t.*, convert(varbinary(max),t.id) as ordered
from @t t
where parent_id = 0
union all
select t.*, ordered + convert(varbinary(max),t.id)
from tree base
 join
 @t t
 on t.parent_id = base.id
 )
select * 
from tree
order by ordered
;
Sign up to request clarification or add additional context in comments.

6 Comments

This doesn't work on my sample table Can you write the query that gives the output I specified above as my expected result? Thanks
I mean CTE gives me all the parent rows first. Then all the children. Not first parent then its children, followed by second parent and its children and so on
I am exactly looking for result used to display this post and its comments. Parent comment and then its replies (children) then another comment and its replies. The replies are the children on parent comment.
The key to this problem is the column used for ordering. I'm sure my query works, just substitute @t for the table you have.
Simple union gives me the result I want after tweaking the query little bit. I think the order by column is the key
|
0

This can be accomplished using two temp tables and three variables.


CREATE TABLE #Parents
(
RowId bigint identity(1,1),
Id    bigint
)

CREATE TABLE #Results ( RowId bigint identity(1,1), Id bigint, ParentId bigint )

DECLARE @Count1 bigint DECLARE @Count2 bigint DECLARE @ParentId bigint

INSERT INTO #Parents SELECT Id FROM MyTable WHERE ParentId = 0 ORDER BY Id

SET @Count1 = 0 SELECT @Count2 = MAX(RowId) FROM #Parents

WHILE @Count1 < @Count2 BEGIN SET @Count1 = @Count1 +1 SELECT @ParentId = Id FROM #Parents WHERE RowId = @Count1 INSERT INTO #Results (Id, ParentId) VALUES (@Count1, 0) INSERT INTO #Results (Id, ParentId) SELECT ID, ParentId FROM MyTable WHERE ID = @Count1 ORDER BY Id END

SELECT Id, ParentId FROM #Results ORDER BY RowId

DROP TABLE #Results DROP TABLE #Parents

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.