2008-10-09 11 views
9

Esta es una pregunta ancestral donde se le da una tabla con los atributos 'tipo', 'variedad' y 'precio', que obtiene el registro con el precio mínimo para cada tipo allí es.Obteniendo Mínimo/Máx. Para cada grupo en ActiveRecord

En SQL, podemos hacer this por:

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

quizá podríamos imitar a esto:

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

¿Hay una aplicación mejor que esto?

+0

cómo obtener el precio máximo y mínimo para cada tipo? – aashish

Respuesta

0

Puede usar # find_by_sql, pero esto implica devolver un objeto modelo, que podría no ser el que desea.

Si quieres ir desnudo al metal, también se puede utilizar # 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 es sólo una herramienta. Lo usas cuando es conveniente. Cuando SQL hace un mejor trabajo, lo usa.

0

He estado peleando con esto por un tiempo y, por el momento, parece que estás muy atascado con la generación de SQL.

Sin embargo, tengo un par de refinamientos para ofrecer.

En lugar de find_by_sql, como sugirió @ François, que he usado de to_sql y joins ActiveRecord a "guía" mi SQL un poco:

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

Como se puede ver, todavía estoy usando SQL prima , pero al menos es solo en la parte donde AR no da soporte (AFAIK ActiveRecord simplemente no puede administrar INNER JOIN ... ON ...) y no en todo el asunto.

El uso de joins en lugar de find_by_sql hace que la consulta se pueda encadenar, puede agregar condiciones adicionales, ordenar la tabla o poner todo en un ámbito.

Cuestiones relacionadas