2011-09-28 94 views
3

如何檢索按Arel中的計數排序的一組記錄?我有一個模型可以跟蹤產品獲得的視圖數量。我想在過去的Y天裏找到最常見的X款產品。按Arel頻率訂購記錄

從MySQL遷移到PostgreSQL時,出現了這個問題,因爲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) 

然而,這種返回模式,而不是實際模型的單一ID。

更新 我去:

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

在反思,這不是真的符合邏輯的期望時,結果是由的GROUP BY和聚合函數結果一個完整的模型,返回的數據(最有可能)不匹配實際模型(行)。

回答

1

您必須將您的select子句擴展爲您希望檢索的所有列。或

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

感謝瑪麗安 - 但是這會產生無效的SQL。默認情況下MySQL對此感到滿意,但不是PostgreSQL。 SELECT子句中的值不存在於GROUP BY或聚合函數中。 – dkam

+0

第一句話是正確的。非常感謝。 – dkam

1

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) 

免責聲明:紅寶石語法是外語給我。