高级MySQL ORDER BY

时间:2011-06-25 23:47:24

标签: php sql sql-order-by

我正在使用PHP和MySQL创建一个基本论坛。我正在为所有线程使用一个表。它名为forum_posts。它有以下几个领域:

id, creator, time, title, message, thread_reply, forum_id, locked, sticky

如果帖子是新主题,则thread_reply设置为0.否则,thread_reply将设置为此帖回复的主题的id。在显示所有线程的页面上,我想在回复它的最后一个帖子的时候对线程进行排序。我正在使用此查询:

SELECT `id`, `title`, `creator` FROM `forum_posts` WHERE `thread_reply` = 0 AND `forum_id` = 1 ORDER BY -`time`

唯一的问题是查询仅在创建线程时排序,而不是最后一次回复到线程的时间。如果您不明白我在说什么,请查看任何论坛的主页,看看它是如何在最后一篇帖子到线程时订购线程的,而不是线程创建的时间。

5 个答案:

答案 0 :(得分:2)

我上周制作了一个自定义论坛(因为phpbb不适合我的需求)。

我首先建议以下结构:

  • 用户表
  • 类别表(论坛的主要部分)
  • 线程表(这些是类别内)
  • 帖子表(这些是单独的帖子)

要通过最后一个操作对帖子进行排序,我只需在Threads表中创建一个名为last_action的字段,或者沿着这些行创建一个字段。

然后,当首次创建线程时,我将该值设置为创建它的日期。然后,无论何时编辑帖子或将新帖子添加到该线程,该值都会更新。这意味着您只需:

SELECT blah, blah, blah FROM threads WHERE cat=4 ORDER BY last_action DESC

希望对你有帮助。

答案 1 :(得分:1)

最简单的方法可能是使用测试thread_reply=0而不是使用测试thread_reply=id。使一个线程启动线程成为对自己的回复。如果你把它用于别的东西,可能会让它变得更乱,但你可以这样做

SELECT * FROM
    (SELECT `id`, `title`, `creator`, b.rtime FROM `forum_posts`
        WHERE a.`thread_reply` = a.`id` AND `forum_id` = 1 ) a
    LEFT JOIN (SELECT `thread_reply`, MAX(`time`) rtime FROM `forum_posts` 
        WHERE `forum_id`=1
        GROUP BY `thread_reply`) b ON a.`id`=b.`thread_reply`
    ORDER BY `rtime` DESC

请注意,第一个子查询是不必要的,但是首次按论坛过滤可能更有效,“它是第一个帖子”。

另外,为什么在使用ORDER BY -time ASC时使用ORDER BY time DESC

但是,是的,最好的办法可能就是有一个主题表和一个回复表。 (主题中的第一个回复是第一个帖子;主题本身没有固有的正文)

答案 2 :(得分:0)

使用

SELECT `op`.`id`, `op`.`title`, `op`.`creator`
FROM `forum_posts` `op`, `forum_posts` `rep`
WHERE (`op`.`thread_reply` = 0 OR `op`.`thread_reply` = `rep`.`id`)
    AND `op`.`forum_id` = 1
ORDER BY IF(`op`.`thread_reply` = 0, -`op`.`time`, -`rep`.`time`)

基本上我在这里做的是找到答案(如果适用)并按时间排序。

答案 3 :(得分:0)

如果你有可能:

创建两个表:

主题:id,subject,date_created,date_last_reply,..

帖子:id,thread_id,date,..

SELECT * FROM threads ORDER BY date_last_reply

答案 4 :(得分:-1)

由于您只是通过该查询获得“开始”帖子,因此您无法通过最新回复订购。您需要添加另一列(last_reply_time等)并让您的应用程序在每次发布新线程时更新该字段,然后按此顺序排序。