MySQL 查询对评论及其嵌套回复进行排序

发布于 2024-11-05 01:02:37 字数 1101 浏览 0 评论 0原文

我在这里和其他地方阅读了 10 多篇相关文章,但仍然无法弄清楚这一点,因为我对 php 和 MySQL 相当陌生:

我正在使用 WordPress 并尝试在旧主题中实现嵌套注释。我的表格已全部设置完毕(我们称之为“评论”),并具有以下字段:

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 完好无损?

I have read over 10 related posts here and elsewhere and still can't figure this one out, being rather new to php and MySQL:

I am using WordPress and trying to implement nested comments within an old theme. My table is all set (let's call it 'comments') and has the following fields:

comment_ID | comment_date | comment_parent, etc.

comment_parent remains equal to 0 in top level comments; it is equal to the comment_ID of the comment replied to in nested replies.

The original MySQL query looks like this:

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

Through the php that follows and outputs the comment list, comments are listed by date without respecting nested replies as such:

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)

Obviously, the sequence is broken since I am sorting by date. Comment 106 should appear right below comment 100, and comment 108 should be below comment 104.

I am trying not to change my php and I would like to do this with the MySQL query but can't get it right. I have tried using JOIN, GROUP BY, HAVING as suggested in similar questions, without any success. Is there a way for me to achieve the correct sorting right from the query and keep my php intact?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你如我软肋 2024-11-12 01:02:37

好吧,我终于想通了,部分归功于上面 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 查询)

和 if true 将 $comments 调整为等于 $replies,以便 WordPress 正确回显我的嵌套评论。然后,我将 $comments 的值返回到其原始值,并退出嵌套注释循环回到主 FOREACH。

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

如需演示,http://www.vincentmounier.com/blog2/ 并单击任意帖子底部的“显示评论”链接。 Nupul,再次感谢您的激励!

Well, I've finally figured it out, thanks partially to Nupul's comment above who said that: "You can first fetch all the top level comments in one go and then the nested comments (all) in the second round and populate your content accordingly.". I had indeed tried that option unsuccessfully, but this motivated me to persevere...

For the record and hoping that this can help someone in the future, here's how I've fixed it. Two separate MySQL queries fetching first the top level comments and second, the nested comment replies (these queries are formatted for 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));

Then I go into my main comment loop (FOREACH) looking for top level comments only. Within that loop, at the bottom, I jump into a nested IF loop looking for nested comments where

$reply->comment_parent == $comment->comment_ID (comparing my 2 MySQL queries)

and if true adjusting $comments to equal $replies so that my nested comments are echoed correctly by WordPress. I then return the value of $comments to its original and exit my nested comment loop back to the main FOREACH.

There are probably flaws in my reasoning or execution but it works like a charm! Of course this does not provide for additional nested levels and all nested comments are written one after the other even if they are replies to each other, but that's good enough for me!

For a demo, http://www.vincentmounier.com/blog2/ and click on any of the "Show Comments" links at the the bottom of posts. Nupul, thanks again for the motivation!

停滞 2024-11-12 01:02:37

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

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

You may be better off changing your table design. One of the better ways to implement nested comments is with Modified Preorder Tree Traversal (MPTT)

This is an article about an MPTT menu, but you should be able to learn how to implement a comment system using a similar scheme.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文