考虑我有15个类别和6个子类别,我有表项目,其中我有一组记录,我必须以下列方式获取
category 1 ---> level 1 ---> 3 items with maximum price
category 1 ---> level 2 ---> 3 items with maximum price
...
...
...
category 15 ---> level 6 ---> 3 items with maximum price
和
@categories.each do |value|
@sub-categories.each do |value1|
array = Item.find(:all, :conditions => ["customer_id IN (?) AND category_id = ? AND sub-category_id = ?", @customer, value.id, value1.id], :order => 'price DESC', :limit => 3)
array.each do |value2|
@max_price_item_of_each_customer << value2
end
end
end
但这会花费很多时间,因为这会迭代。那么我怎么能以这种方式改变这个时间呢?任何帮助表示赞赏。
答案 0 :(得分:4)
尝试:
@max_price_item_of_each_customer = []
@categories.each do |value|
@max_price_item_of_each_customer += Item.find(:all, :conditions => ["customer_id IN (?) AND category_id = ? AND sub-category_id in (?)", @customer, value.id, @sub-categories.map(&:id)], :order => 'price DESC', :limit => 3)
end
答案 1 :(得分:2)
这一切都取决于您正在使用的记录的规模,但如果您使用合理的设置,这应该更快,并将您的查询减少到1.
@customer_id = 1
@categories = [1, 2, 3]
@subs = [4, 5, 6]
@max_price_item_of_each_customer = []
items = Item.where(customer_id: @customer, category_id: @categories, subcategory_id: @subcategories)
items.group_by{|item| item.category_id}.each_pair do |category_id, category_items|
category_items.group_by{|item| item.subcategory_id}.each_pair do |subcategory_id, subcategory_items|
@max_price_item_of_each_customer += subcategory_items.sort{|x, y| y.price <=> x.price }.first(3)
end
end
答案 2 :(得分:1)
如果您使用Postgresql,下面的解决方案可能会有效。
items
表中选择一组3个项ID,按price
降序排序,按category_id
和subcategory_id
分组。您可以使用Postgres array_agg
在分组后收集项ID。category_id
升序,subcategory_id
升序和price
降序结果为ActiveRecord::Relation
,因此您可以像往常一样迭代这些项目。由于结果是扁平化的(但已经按类别,子类别和价格排序),您需要自己分离不同的类别和子类别。
grouped_item_ids = Item.where(customer_id: customer_id).
select("items.category_id, items.subcategory_id, (array_agg(items.id order by items.price desc))[1:3] AS item_ids").
group("items.category_id, items.subcategory_id").map {|item| item["item_ids"]}
@items = Item.where(id: grouped_item_ids.flatten).
order("items.category_id ASC, items.subcategory_id ASC, items.price desc")
答案 3 :(得分:1)
以下查询适用于我
@max_price_item_of_each_customer =Item.find_by_sql(["SELECT i1.* FROM item i1
LEFT OUTER JOIN item i2 ON (i1.category_id = i2.category_id AND i1.sub-category_id = i2.sub-category_id AND i1.id < i2.id)
WHERE i1.customer_id IN (?) AND i1.category_id IN (?)
GROUP BY i1.id HAVING COUNT(*) < 3
ORDER BY price DESC", @customer, @categories.map(&:id)])