Как отсортировать пользователей по самому последнему сообщению?

#sql #ruby-on-rails #ruby-on-rails-3 #activerecord

#sql #ruby-on-rails #ruby-on-rails-3 #activerecord

Вопрос:

У меня есть две модели: User , и Post которая имеет user_id столбец (внешний ключ) и created_at column.

Я хотел бы отсортировать пользователей по самому последнему сообщению. Например, если:

 user_id = 1, created 3 posts at: 17/05/2011, 19/05/2011, 21/05/2011
user_id = 2, created 1 post at: 22/05/2011
user_id = 3, created 2 posts at: 18/05/2011, 20/05/2011
  

результат должен быть:

 user_id = 2
user_id = 1
user_id = 3
  

Как бы вы добились этого в Rails 3?

Ответ №1:

Не уверен насчет части RoR, но вы просматриваете инструкцию group by:

 select user_id, max(created_at) as created_at
from posts
group by user_id
order by max(created_at) desc
  

Ответ №2:

Должно быть что-то вроде:

 Post.select(:user_id).group(:user_id).order("created_at DESC")
  

Комментарии:

1. Это неправильно. Если, например, есть 3 пользователя, и у каждого пользователя есть одно сообщение, User.joins(:posts).size будет 10, а не 3.

2. Это почти правильно. После того, как я изменил это на order("max(created_at) DESC") , как предложил Денис, похоже, что это помогает. Хотя я все еще не уверен, какой сорт делается без max

3. @Misha: Я предполагаю, что вы используете MySQL внизу. В этом случае order(«created_at DESC») будет использовать поле created_at одной из строк в группе — другими словами, вы получите случайный порядок. (Другие движки отклонили бы это предложение с ошибкой.)

Ответ №3:

Если вы хотите отсортировать по последнему сообщению, вы можете положиться на то, что строка с наибольшим id значением является самой последней:

 Post.select(:user_id).group(:user_id).order("MAX(id) DESC")
  

Таким образом, вы можете использовать существующий индекс первичного ключа в id столбце (и избежать необходимости добавлять новый индекс в created_at столбец).