0

我正在为具有父/子关系的论坛存储线程,如下所示:

CREATE TABLE forum_threads (
  thread_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  parent_id INTEGER UNSIGNED NOT NULL DEFAULT 0,
  topic_id INTEGER UNSIGNED NOT NULL,
  user_id INTEGER UNSIGNED NOT NULL,
  title VARCHAR(100) NOT NULL,
  body TEXT NOT NULL,
  create_date DATETIME NOT NULL,

  PRIMARY KEY (thread_id),
  FOREIGN KEY (parent_id)
    REFERENCES forum_threads(thread_id),
  FOREIGN KEY (topic_id)
    REFERENCES forum_topics(topic_id),
  FOREIGN KEY (user_id)
    REFERENCES users(user_id)
);

新线程有parent_id = 0,而回复有parent_id = the thread being replied to。现在我感到困惑的是,我想显示按最近回复排序的线程列表:

SELECT * FROM forum_threads
WHERE topic_id = :topic_id AND parent_id = 0
ORDER BY ??? DESC LIMIT :start, :display

不知道如何做到这一点?

4

3 回答 3

3

如果父母不能有父母,您可以使用这样的查询:

SELECT *
FROM forum_threads
ORDER BY
  CASE WHEN parent_id=0 THEN thread_id ELSE parent_id END DESC,
  Parent_id!=0,
  thread_id DESC

这将按降序列出所有线程,回复按最近的一个排序。

于 2013-06-30T21:48:58.530 回答
2

如果我正确理解结构,回复是那些parent_id指向thread_id“父”线程的行。

如果是这种情况,像这样的自联接将起作用 - 请注意,SELECT *必须这样做,因为(a)您从两个表中进行选择,因此*意味着“两个表中的所有行”和(b)您需要GROUP BY特定列:

SELECT
  parent.thread_id,
  parent.parent_id,
  parent.topic_id,
  parent.user_id,
  parent.title,
  parent.body,
  parent.create_date,
  MAX(reply.create_date) AS reply_date
FROM forum_threads parent
INNER JOIN forum_threads reply ON parent.thread_id = reply.parent_id
WHERE topic_id = whatever AND parent_id = 0
GROUP BY
  parent.thread_id,
  parent.parent_id,
  parent.topic_id,
  parent.user_id,
  parent.title,
  parent.body,
  parent.create_date
ORDER BY reply_date DESC
于 2013-06-30T21:54:02.963 回答
1

像这样的东西也可以工作:

SELECT * FROM forum_threads `t1`
WHERE topic_id = :topic_id AND parent_id = 0
ORDER BY (SELECT `create_date` FROM `forum_threads` WHERE `parent_id`=`t1`.`thread_id` ORDER BY `create_date` DESC LIMIT 1) DESC LIMIT :start, :display

如果您需要访问已回复的日期(我的需要另一个子查询),Ed Gibbs 的解决方案会更好,但如果您不需要它,这是一个更简单的解决方案(恕我直言)。

于 2013-06-30T22:10:48.630 回答