显示带有查询的帖子层次结构

时间:2014-09-17 04:46:01

标签: sql sql-server

我正在构建一个简单的线程/讨论机制,但是我很难创建一个查询来检索我的帖子,就像树/帖子层次结构一样。

我有一个POSTS表,其中包含以下属性(简化):id,text,username,type,replytoid

键入:'THREAD START'或'REPLY'
replytoid:评论正在回复另一个评论,所以我在这里存储了'父'id。 “THREAD START”有一个NULL replytoid。

我的测试数据是:(fiddle

| ID |             TEXT | USERNAME |                 TYPE | REPLYTOID |
|----|------------------|----------|----------------------|-----------|
|  1 | My name is Alice |    Alice | THREAD START         |    (null) |
|  2 |  Reply to @Alice |      Bob | REPLY                |         1 |
|  3 |    Reply to @Bob |    Carol | REPLY                |         2 |
|  4 |  Reply to @Carol |     Dave | REPLY                |         3 |
|  5 |  Reply to @Alice |      Eve | REPLY                |         1 |
|  6 | My name is Frank |    Frank | THREAD START         |    (null) |
|  7 |  Reply to @Frank |     Gina | REPLY                |         6 |

我尝试了很多种JOIN,但我无法实现预期的输出,即:

| ID |             TEXT | USERNAME |            TYPE | REPLYTOID | LEVEL | THREADID |
|----|------------------|----------|-----------------|-----------|-------|----------|
|  1 | My name is Alice |    Alice | THREAD START    |    (null) |     1 |        1 |
|  2 |  Reply to @Alice |      Bob | REPLY           |         1 |     2 |        1 |
|  5 |  Reply to @Alice |      Eve | REPLY           |         1 |     2 |        1 |
|  3 |    Reply to @Bob |    Carol | REPLY           |         2 |     3 |        1 |
|  4 |  Reply to @Carol |     Dave | REPLY           |         3 |     4 |        1 |
|  6 | My name is Frank |    Frank | THREAD START    |    (null) |     1 |        6 |
|  7 |  Reply to @Frank |     Gina | REPLY           |         6 |     2 |        6 |

1 个答案:

答案 0 :(得分:1)

这是一个可以使用递归CTE的问题的一个很好的例子。从根帖子开始作为锚点,并建立将它们链接到父母的回复。您可以通过保留父ID来增加先前的级别和线程来获得级别。

with cte as
(
  select *, 1 as level, id as thread
  from posts
  where replytoid is null

  union all

  select posts.*, cte.level + 1 as level, cte.thread 
  from posts
  inner join cte on cte.id = posts.replytoid
)

select * from cte
order by thread, level

SQL Fiddle