Reputation: 477
I am trying to come up with a query that will return comments following their replies and its replies.
Something like
comment 1
reply 1.1
reply 1.1.1
reply 1.2
comment 2
comment 3
comment 3.1
etc
I have this so far
SELECT [CommentID]
,[ParentID]
,[Message]
, ROW_NUMBER() over(partition by ParentID order by CommentID ) as rn
,[CreatedBy]
,[CreatedDate]
FROM [DBNAME].[dbo].[Commenttable]
GROUP BY [CommentID],[ParentID],[CreatedDate],[Message],[CreatedBy]
but what I get is
comment 1
comment 2
comment 3
reply 1.1
reply 1.2
reply 3.1
reply 1.1.1
Basic Structure is just a table with Comment ID, Parent ID, and the message. The comments and replies are just to help explain what I am trying to achieve
Upvotes: 1
Views: 1070
Reputation: 15816
Give this a try:
declare @CommentTable as Table ( CommentId Int Identity, ParentId Int Null, Message VarChar(16) )
insert into @CommentTable ( ParentId, Message ) values
( null, '1' ),
( null, '2' ), ( 1, '1.1' ),
( null, '3' ), ( 4, '3.1' ), ( 3, '1.1.1' ), ( 1, '1.2' )
select * from @CommentTable
; with Cindy as (
-- Start with the base comments.
select CommentId, ParentId, Message, Row_Number() over ( order by CommentId ) as Number,
Cast( Row_Number() over ( order by CommentId ) as VarChar(1000) ) as Path,
Cast( Right( '0000' + Cast( Row_Number() over ( order by CommentId ) as VarChar(4) ), 5 ) as VarChar(1000) ) as OrderPath
from @CommentTable
where ParentId is NULL
union all
-- Add replies on layer at a time.
select CT.CommentId, CT.ParentId, CT.Message, Row_Number() over ( order by CT.CommentId ),
Cast( C.Path + '.' + Cast( Row_Number() over ( order by CT.CommentId ) as VarChar(4) ) as VarChar(1000) ),
Cast( C.OrderPath + Right( '0000' + Cast( Row_Number() over ( order by CT.CommentId ) as VarChar(4) ), 5 ) as VarChar(1000) )
from @CommentTable as CT inner join
Cindy as C on C.CommentId = CT.ParentId
)
select *
from Cindy
order by OrderPath
Upvotes: 3