6

Cân nhắc tôi có 15 loại và 6 tiểu mục và tôi có các mục bảng nơi mà tôi đã tập hợp hồ sơ, nơi tôi phải lấy theo cách sau đâyLàm thế nào để chuyển các truy vấn để thực hiện hiệu quả trong đường ray?

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 

nhưng điều này sẽ mất nhiều thời gian vì điều này lặp lại. Vì vậy, làm thế nào tôi có thể thay đổi điều này theo cách như vậy thời gian có thể được giảm? Bất kỳ trợ giúp được đánh giá cao.

+1

Bạn có thể cho một ví dụ cụ thể về những gì một loại, Level và mục có thể được? Tôi đang gặp khó khăn trong việc hiểu cấu trúc dữ liệu của bạn. – Matthew

Trả lời

2

này tất cả phụ thuộc vào quy mô của hồ sơ bạn đang làm việc với, nhưng nếu bạn đang làm việc với một tập hợp lý, điều này cần được nhanh hơn và sẽ tăng tốc truy cập của bạn để 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 
+0

Thankyou và điều này làm việc cho tôi với một chỉnh sửa nhỏ. Bạn đã bỏ lỡ dấu bằng sau "@max_price_item_of_each_customer +" mà tôi đã thử chỉnh sửa nhưng tôi không thể vì nó là thay đổi duy nhất. – logesh

4

Hãy thử:

@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 
+0

Tôi sẽ thử điều này. Nhưng trước đó, bạn có thể vui lòng cho tôi biết cách này sẽ tìm nạp 3 mục từ mỗi danh mục phụ. Tôi nghĩ rằng điều này sẽ lấy 3 mục cho mỗi loại. – logesh

+0

Tôi đã thử và chọn 3 mục cho mỗi danh mục chứ không phải cho từng danh mục phụ. – logesh

1

Giải pháp dưới đây có thể hoạt động nếu bạn sử dụng Postgresql.

  1. Chọn một nhóm 3 ids mục từ items bảng, sắp xếp theo price giảm dần và được phân nhóm theo category_idsubcategory_id. Bạn có thể sử dụng Postgres array_agg để thu thập các id mục sau khi nhóm.
  2. Chọn mục hàng, trong đó id mục nằm trong các id mục được nhóm đó. Sau đó, đặt kết quả bởi category_id tăng dần, subcategory_id tăng dần, và price giảm dần

Kết quả là ActiveRecord::Relation, vì vậy bạn có thể lặp lại các mặt hàng như bình thường. Vì kết quả được làm phẳng (nhưng đã được sắp xếp theo danh mục, danh mục con và giá), bạn cần tách riêng các danh mục và danh mục phụ khác nhau.

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") 
1

truy vấn sau làm việc cho tôi

@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)]) 
Các vấn đề liên quan