我有2张桌子。产品和商店。产品属于商店。
我想按照上个月创建的降序排序商店。到目前为止,我有......
Product.where("created_at > ?", 1.month.ago).group_by { |p| p.store }.sort_by { |k,v| v.count }.reverse.map{|a| a[0]}
但是这作为group_by函数非常慢。我应该注意到我正在使用PostgreSQL,这意味着我在互联网上找到的一些解决方案对我没用。
答案 0 :(得分:0)
假设您只想计算在上个月"" (从"现在"倒数):
SELECT store_id
FROM product
WHERE created_at > now() - interval '1 month'
GROUP BY store_id
ORDER BY count(*) DESC;
我甚至没有包含store
表。如果没有任何合格产品,您只能获得store_id
而没有商店。这是最快的。
created_at
上的索引将起到重要作用。 (created_at, store_id)
上的多列索引将进一步优化。更昂贵,更专业,但对于手头的查询更快。在pg 9.2+中你可以得到index-only scans。
要包含store
表的列以及包含0个合格产品的商店:
SELECT s.*
FROM store s
LEFT JOIN (
SELECT store_id, count(*) AS ct_prod
FROM product
WHERE created_at > now() - interval '1 month'
GROUP BY store_id
) p ON s.store_id = p.store_id
ORDER BY p.ct_prod DESC NULL LAST, s.store_id;
NULLS LAST
对于最后没有任何匹配的行进行排序至关重要
我添加了s.store_id
作为任意关系,以便为具有相同ct_prod
的商店获得一致的排序顺序。