#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
столбец).