开发者

Query for a threaded discussion

开发者 https://www.devze.com 2023-03-26 05:39 出处:网络
I have a single table with a self reference InReplyTo with some data like this: PostID InReplyTo Depth

I have a single table with a self reference InReplyTo with some data like this:

PostID InReplyTo Depth
------ --------- -----
1      null      0
2      1         1
3      1         1
4      2         2
5      3         2
6      4         3
7      1         1
8      5         3
9      2         2

I want to write a query that will return this data in it's threaded form so that the post with ID=2 and all it's descendants will output开发者_StackOverflow社区 before PostID=3 and so on for unlimited depth

PostID InReplyTo Depth
------ --------- -----
1      null      0
2      1         1
4      2         2
6      4         3
9      2         2
3      1         1
5      3         2
8      5         3
7      1         1

Is there a simple way to achieve this? I am able to modify the DB structure at this stage so would the new hierarchy datatype be the easiest way to go? Or perhaps a recursive CTE?


-- Test table
declare @T table (PostID int, InReplyTo int, Depth int)

insert into @T values  (1,  null, 0), (2,  1,  1), (3,  1,  1), (4,  2,  2), 
(5,  3,  2), (6,  4,  3), (7,  1,  1), (8,  5,  3),(9,  2,  2)

-- The post to get the hierarchy from
declare @PostID int = 1

-- Recursive cte that builds a string to use in order by
;with cte as
(
  select T.PostID,
         T.InReplyTo,
         T.Depth,
         right('0000000000'+cast(T.PostID as varchar(max)), 10)+'/' as Sort
  from @T as T
  where T.PostID = @PostID
  union all
  select T.PostID,
         T.InReplyTo,
         T.Depth,
         C.Sort+right('0000000000'+cast(T.PostID as varchar(max)), 10)+'/'
  from @T as T
    inner join cte as C
      on T.InReplyTo = C.PostID
)
select PostID,
       InReplyTo,
       Depth,
       Sort
from cte
order by Sort

Result:

PostID      InReplyTo   Depth       Sort
----------- ----------- ----------- --------------------------------------------
1           NULL        0           0000000001/
2           1           1           0000000001/0000000002/
4           2           2           0000000001/0000000002/0000000004/
6           4           3           0000000001/0000000002/0000000004/0000000006/
9           2           2           0000000001/0000000002/0000000009/
3           1           1           0000000001/0000000003/
5           3           2           0000000001/0000000003/0000000005/
8           5           3           0000000001/0000000003/0000000005/0000000008/
7           1           1           0000000001/0000000007/


What you are looking for is indeed a recursive query.

A matching example to your case can be found here

0

精彩评论

暂无评论...
验证码 换一张
取 消