Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何使用父/子关系对数据进行排序_Mysql - Fatal编程技术网

Mysql 如何使用父/子关系对数据进行排序

Mysql 如何使用父/子关系对数据进行排序,mysql,Mysql,我正在为具有父/子关系的论坛存储线程,如下所示: 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(10

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

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\u id=0
,而回复具有
parent\u id=被回复的线程
。现在我感到困惑的是,我想显示一个由最新回复排序的线程列表:

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

不确定如何完成此操作?

如果父级不能拥有父级,可以使用如下查询:

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

这将按降序列出所有线程,并按最近的线程排序答复。

如果父线程不能拥有父线程,则可以使用如下查询:

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

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

如果我正确理解结构,则回复是那些带有
父线程id
的行,它们指向“父”线程的
线程id

如果是这种情况,像这样的自联接将起作用-请注意,
SELECT*
必须退出,因为(a)您从两个表中进行选择,因此
*
表示“两个表中的所有行”,并且(b)您需要按照特定列对
进行分组:

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

如果我正确理解了结构,那么回复是那些带有
parent\u id
的行,它们指向“parent”线程的
thread\u id

如果是这种情况,像这样的自联接将起作用-请注意,
SELECT*
必须退出,因为(a)您从两个表中进行选择,因此
*
表示“两个表中的所有行”,并且(b)您需要按照特定列对
进行分组:

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

类似的方法也可以:

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的解决方案更好,如果您需要访问回复日期(我的需要另一个子查询),但如果您不需要,这是一个更简单的解决方案(IMHO)。

类似的解决方案也可以:

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的解决方案更好,如果你需要访问回复日期(我的需要另一个子查询),但如果你不需要它,这是一个更简单的解决方案(IMHO)。

对我来说是一个外部问题:
是什么意思?(例如
:topic_id
:start
?@PRPGFerret我使用的是PDO包装,
是用于准备语句的占位符。我的外部问题是:
是什么意思?(例如
:topic_id
:start
?@PRPGFerret我使用的是PDO包装,
是用于准备语句的占位符。嗨,这几乎是完美的,唯一的问题是没有子项(答复)如果存在,我希望它默认为parent.create_date。每当线程没有子线程时,它似乎返回一个空结果集。嗨,Ed,这几乎是完美的,唯一的问题是没有子线程(答复)如果存在,我希望它默认为parent.create_date。每当线程没有子线程时,它似乎会返回一个空结果集。这对我来说太完美了!这对我来说太完美了!