2008-10-09 39 views
9

Đây là câu hỏi cũ khi được cung cấp một bảng có thuộc tính 'loại', 'giống' và 'giá', mà bạn tìm nạp bản ghi với giá tối thiểu cho mỗi loại Là.Tìm nạp tối thiểu/tối đa cho mỗi nhóm trong ActiveRecord

Trong SQL, chúng ta có thể làm this bởi:

select f.type, f.variety, f.price 
from ( select type, min(price) as minprice from table group by type) as x 
inner join table as f on f.type = x.type and f.price = x.minprice;` 

Chúng tôi có lẽ có thể bắt chước điều này bằng cách:

minprices = Table.minimum(:price, :group => type) 
result = [] 
minprices.each_pair do |t, p| 
    result << Table.find(:first, :conditions => ["type = ? and price = ?", t, p]) 
end 

Có một thực hiện tốt hơn thế này?

+0

làm thế nào để có được giá tối đa và tối thiểu cho từng loại ?? – aashish

Trả lời

0

Bạn có thể sử dụng # find_by_sql, nhưng điều này ngụ ý trả về đối tượng mô hình, có thể không phải là thứ bạn muốn.

Nếu bạn muốn đi trần với kim loại, bạn cũng có thể sử dụng # select_values:

data = ActiveRecord::Base.connection.select_values(" 
     SELECT f.type, f.variety, f.price 
     FROM (SELECT type, MIN(price) AS minprice FROM table GROUP BY type) AS x 
     INNER JOIN table AS f ON f.type = x.type AND f.price = x.minprice") 
puts data.inspect 
[["type", "variety", 0.00]] 

ActiveRecord chỉ là một công cụ. Bạn sử dụng nó khi nó thuận tiện. Khi SQL làm một công việc tốt hơn, bạn sử dụng nó.

0

Tôi đã chiến đấu với điều này trong một thời gian và cho đến thời điểm này có vẻ như bạn đang khá nhiều khó khăn với việc tạo ra SQL.

Tuy nhiên, tôi có một vài cải tiến để cung cấp.

Thay vì find_by_sql, như @ François đề nghị, tôi đã sử dụng ActiveRecord của to_sqljoins để "hướng dẫn" SQL của tôi một chút:

subquery_sql = Table.select(["MIN(price) as price", :type]).group(:type).to_sql 
joins_sql = "INNER JOIN (#{subquery_sql}) as S 
       ON table.type = S.type 
       AND table.price = S.price" 

Table.joins(joins_sql).where(<other conditions>).order(<your order>) 

Như bạn thấy, tôi vẫn sử dụng SQL thô , nhưng ít nhất nó chỉ là một phần mà AR không hỗ trợ (AFAIK ActiveRecord chỉ đơn giản là không thể quản lý INNER JOIN ... ON ...) và không phải trên toàn bộ điều.

Sử dụng joins thay vì find_by_sql làm cho truy vấn có thể chuỗi - bạn có thể thêm điều kiện bổ sung hoặc sắp xếp bảng hoặc đặt mọi thứ trong phạm vi.

0

Để cập nhật câu trả lời Avdi của trên:

Table.minimum (: giá cả,: group =>: type)

Dưới đây là URL Cập nhật:

http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-minimum

+1

Có lẽ một liên kết đến một phiên bản cập nhật của Rails sẽ hữu ích. Bạn không chắc chắn lý do tại sao bạn chọn liên kết với 2 phiên bản chính trước đây. –

+0

Cảm ơn Isaac. Đã cập nhật. – danielmbarlow

Các vấn đề liên quan