用于排序评论及其嵌套回复的MySQL查询



我已经在这里和其他地方读了超过10篇相关的文章,仍然不能弄清楚这个,对php和MySQL相当陌生:

我正在使用WordPress并试图在旧主题中实现嵌套注释。我的表已经设置好了(我们称之为"comments"),并且有以下字段:

comment_ID | comment_date | comment_parent, etc.

comment_parent在顶级注释中保持等于0;它等于嵌套回复中回复的评论的comment_ID

原来的MySQL查询是这样的:

SELECT * FROM $wpdb->comments 
WHERE comment_post_ID = %d AND comment_approved = '1' 
ORDER BY comment_date ASC LIMIT %d"

通过后跟并输出注释列表的php,注释按日期列出,而不考虑嵌套的回复,如:

comment_ID | comment_date | comment_parent
100          Jan 01         0      (this is a top level comment)
104          Jan 03         0      (this is a top level comment)
106          Jan 04         100    (this is a reply to the first comment)
108          Jan 05         104    (this is a reply to the second comment)

显然,序列被打破了,因为我是按日期排序的。评论106应该出现在评论100的正下方,评论108应该出现在评论104的正下方。

我试图不改变我的php,我想这样做与MySQL查询,但不能得到它的权利。我试过使用JOIN, GROUP BY, HAVING在类似的问题中建议,没有任何成功。是否有一种方法可以让我从查询中获得正确的排序并保持php完整?

好吧,我终于弄明白了,部分感谢Nupul上面的评论,他说:"你可以首先一次取出所有顶级评论,然后在第二轮取出嵌套的评论(所有),并相应地填充你的内容。"我确实尝试过那个选项,但没有成功,但这激励我坚持下去……

为了记录和希望这可以帮助别人在未来,这是我如何解决它。两个独立的MySQL查询首先获取顶层评论,其次获取嵌套评论回复(这些查询是为WordPress格式化的)

$comments = $wpdb->get_results($wpdb->prepare("
  SELECT * 
  FROM $wpdb->comments 
  WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_parent = '0' 
  ORDER BY comment_date ASC 
  LIMIT %d
",etc,etc)); 
$replies = $wpdb->get_results($wpdb->prepare("
  SELECT * 
  FROM $wpdb->comments 
  WHERE comment_post_ID = %d AND comment_approved = '1' AND comment_parent <> '0' 
  ORDER BY comment_date ASC 
  LIMIT %d
",etc,etc));
然后进入主注释循环(FOREACH),只查找顶层注释。在该循环的底部,我跳入一个嵌套IF循环,查找

$reply->comment_parent == $comment->comment_ID(比较我的2个MySQL查询)

,如果为真,调整$comments使其等于$replies,这样我的嵌套注释就会被WordPress正确地响应。然后,我将$comments的值返回到其原始值,并退出嵌套注释循环,返回到主FOREACH。

我的推理或执行可能有缺陷,但它像一个魅力!当然,这并没有提供额外的嵌套级别,所有嵌套注释都是一个接一个地写的,即使它们是彼此的回复,但这对我来说已经足够了!

要演示,请访问http://www.vincentmounier.com/blog2/并单击帖子底部的任何"Show Comments"链接。Nupul,再次感谢你的激励!

您最好更改您的表设计。实现嵌套注释的一个更好的方法是使用修改预序树遍历(MPTT)

这是一篇关于MPTT菜单的文章,但是您应该能够学习如何使用类似的方案实现评论系统。

最新更新