Упорядочивание записей по частоте с Арелем - PullRequest
3 голосов
/ 28 сентября 2011

Как мне получить набор записей, упорядоченных по количеству в Ареле? У меня есть модель, которая отслеживает, сколько просмотров получает продукт. Я хочу найти наиболее часто просматриваемые продукты за последние Y дней.

Эта проблема возникла при переходе на PostgreSQL с MySQL, поскольку MySQL немного прощает то, что он примет. Этот код из модели View работает с MySQL, но не с PostgreSQL, поскольку в вывод включаются неагрегированные столбцы.

scope :popular, lambda { |time_ago, freq|
  where("created_on > ?", time_ago).group('product_id').
    order('count(*) desc').limit(freq).includes(:product)
}

Вот что у меня так далеко:

View.select("id, count(id) as freq").where('created_on > ?', 5.days.ago).
  order('freq').group('id').limit(5)

Однако, это возвращает единственный идентификатор модели, а не фактическую модель.

Обновление Я пошел с:

select("product_id, count(id) as freq").
  where('created_on > ?', time_ago).
  order('freq desc').
  group('product_id').
  limit(freq)

Если подумать, то не совсем логично ожидать, что полная модель будет состоять из результатов, представленных GROUP BY, и результатов агрегированных функций, поскольку возвращаемые данные (скорее всего) не будут соответствовать реальной модели (строке).

Ответы [ 2 ]

1 голос
/ 29 сентября 2011

SQL будет:

SELECT product_id, product, count(*) as freq
 WHERE created_on > '$5_days_ago'::timestamp
 GROUP BY product_id, product
 ORDER BY count(*) DESC, product
 LIMIT 5;

Экстраполируя из вашего примера, оно должно быть:

View.select("product_id, product, count(*) as freq").where('created_on > ?', 5.days.ago).
  order("count(*) DESC" ).group('product_id, product').limit(5)

Отказ от ответственности: синтаксис Ruby для меня является иностранным языком.

1 голос
/ 28 сентября 2011

Вы должны расширить предложение select на все столбцы, которые хотите получить.или

select("views.*, count(id) as freq")
...