Расширенный MySQL ORDER BY - PullRequest
       0

Расширенный MySQL ORDER BY

1 голос
/ 26 июня 2011

Я делаю основной форум, используя 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 ]

2 голосов
/ 26 июня 2011

На прошлой неделе я создал собственный форум (так как phpbb просто не отвечал моим потребностям).

Сначала я бы посоветовал следующую структуру:

  • таблица для пользователей
  • таблица категорий (основные разделы форума)
  • таблица для потоков (это внутри категории)
  • таблица сообщений (это в отдельных темах)

Чтобы упорядочить сообщения по последнему действию, я просто создал поле в таблице «Потоки», которое называлось last_action или что-то в этом духе.

Затем, когда поток впервые создается, я устанавливаю это значение на дату его создания. Затем, когда сообщение редактируется или в него добавляется новое сообщение, это значение обновляется. Это значит, что вы просто делаете:

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

Надеюсь, это поможет вам.

1 голос
/ 26 июня 2011

Самый простой способ - это сделать так, чтобы вместо теста 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

Обратите внимание, что первый подзапрос не нужен, однако, вероятно, более эффективно сначала выполнить фильтрацию поforum и "это первое сообщение".

Кроме того, зачем использовать ORDER BY -time ASC, когда вы можете использовать ORDER BY time DESC?

Но да, лучший способ, вероятно, просто иметь таблицупо темам и таблица ответов.(Первый ответ в теме - это первое сообщение; сама тема не имеет основного текста)

0 голосов
/ 26 июня 2011

Использование

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`)

В основном, что я здесь делаю, так это нахожу ответ, если это применимо, и заказываю его по времени.

0 голосов
/ 26 июня 2011

Если у вас есть возможность:

Создайте две таблицы:

Темы : идентификатор, тема, дата создания, дата_последовательность, ..

Сообщений : идентификатор, идентификатор_треды, дата, ..

SELECT * FROM threads ORDER BY date_last_reply
0 голосов
/ 26 июня 2011

Поскольку вы получаете только «стартовую» запись с этим запросом, у вас нет способа упорядочить по последнему ответу.Вам нужно добавить еще один столбец (last_reply_time и т. Д.) И заставить ваше приложение обновлять это поле каждый раз, когда публикуется новая тема, а затем заказывать по ней.

...