我正在构建一个简单的线程/讨论机制,但是我很难创建一个查询来检索我的帖子,就像树/帖子层次结构一样。
我有一个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 |
答案 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