2008-10-09 10 views
9

Это вековой вопрос, где задана таблица с типами атрибутов, «разнообразием» и «ценой», которую вы берете с минимальной ценой для каждого типа является.Получение минимальной/максимальной для каждой группы в ActiveRecord

В SQL, мы можем сделать this по:

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;` 

Мы могли бы, возможно, подражать этим путем:

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

Есть ли лучше реализация, чем это?

+0

как получить максимальную и минимальную цену за каждый тип? – aashish 2016-08-18 16:38:13

ответ

0

Вы можете использовать # find_by_sql, но это подразумевает возврат объекта модели, который может быть не таким, каким вы хотите.

Если вы хотите идти голой на металл, вы можете также использовать # 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 это просто инструмент. Вы используете его, когда это удобно. Когда SQL выполняет лучшую работу, вы используете это.

0

Я боролся с этим некоторое время, и на данный момент кажется, что вы в значительной степени зациклились на генерации SQL.

Однако у меня есть несколько уточнений.

Вместо find_by_sql как @ предложил Франсуа, я использовал ActiveRecord-х to_sql и joins на «руководство» мой SQL немного:

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

Как вы можете видеть, я до сих пор используют необработанный SQL , но, по крайней мере, это только со стороны, когда AR не дает поддержки (AFAIK ActiveRecord просто не может управлять INNER JOIN ... ON ...), а не от всего.

Использование joins вместо find_by_sql делает запрос цепочкой - вы можете добавить дополнительные условия или отсортировать таблицу или поместить все в область.

0

Чтобы обновить ответ AVDI в выше:

Table.minimum (: цены,: группа =>: тип)

Вот обновленный URL:

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

+1

Возможно, ссылка на более современную версию Rails будет полезна. Не знаете, почему вы выбрали ссылку на 2 основных версии назад. – 2014-07-08 18:50:04

 Смежные вопросы

  • Нет связанных вопросов^_^