0

我设置了一个应用程序,其中包含附加到帖子的嵌套评论。我决定使用闭包表方法(幻灯片 40)来发表评论,因为硬盘空间是多么便宜,而查询和管理树结构似乎多么容易。但是,我遇到了一个问题。我似乎无法弄清楚如何根据帖子 ID 而不是祖先 ID(幻灯片 49)获取树路径。

我的数据库结构如下所示:

table: comment_paths
--------------------
parent_id (fk on comments.id)
child_id  (fk on comments.id)
depth

table: comments
---------------
id
parent_id (fk on comments.id)
post_id   (fk on posts.id)
text

table: posts
---------------
id
name

如果我事先知道 parent_id,就像在幻灯片中一样,抓取树很简单:

SELECT c.*, p.*
FROM comments AS c
JOIN comment_paths AS p
ON c.id = p.child_id
WHERE p.parent_id = 1

parent_id但是,我事先不知道;我只知道post_id. 数据库的设置方式,与帖子关联的树不止一棵:

                 [post]
-----------------------------------------
[comment]       [comment]       [comment]   depth: 0
    |                               |
 [reply]                         [reply]    depth: 1
  |   |
 [r] [r]                                    depth: 2

我最初的解决方案是这样的查询:

SELECT c.*, p.*
FROM comments AS c
JOIN comment_paths AS p
ON c.id = p.child_id
WHERE p.parent_id IN
    (SELECT id FROM comments WHERE parent_id IS NULL AND post_id = 6)

它返回正确的数据,但我觉得这样的嵌套 SELECT 是不正确的。有一个更好的方法吗?

谢谢!

4

1 回答 1

2

我实在想不出更好的办法。我要做的唯一改变是使用 EXISTS 而不是 IN:

SELECT c.*, p.*
FROM comments AS c
JOIN comment_paths AS p
ON c.id = p.child_id
WHERE EXISTS
(SELECT * FROM comments c2 WHERE p.parent_id = c2.id AND c2.parent_id IS NULL AND c2.post_id = 6)

我很想看看是否真的有更好的方法。

更新:

我不确定您使用的是什么 RDMS。但是,如果递归查询可用,我认为您可以完全摆脱 comments_path 表:

;with cte as(
select c.*, 0 as depth
from comments c
where c.post_id = 6 and c.parent_id is null
union all
select c.*, cte.depth + 1
from comments c
join cte on c.parent_id = cte.id)

select * from cte
于 2013-04-17T17:09:29.703 回答