rails column active activerecord group-by aggregate-functions minimum

column - Obteniendo Mínimo/Máximo para cada grupo en ActiveRecord



sum active record (4)

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

Si quiere ir al descubierto, también puede usar # 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 solo una herramienta. Lo usas cuando es conveniente. Cuando SQL hace un mejor trabajo, lo usa.

Esta es una pregunta ancestral en la que se le da una tabla con los atributos ''tipo'', ''variedad'' y ''precio'', que usted obtiene el registro con el precio mínimo para cada tipo que hay.

En SQL, podemos hacer esto de la siguiente manera:

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ás podríamos imitar esto por:

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 mejor implementación que esta?


He estado luchando con esto por un tiempo y, por el momento, parece que estás bastante atrapado en la generación de SQL.

Sin embargo, tengo un par de mejoras para ofrecer.

En lugar de find_by_sql , como sugirió @ François, he usado ActiveRecord''s to_sql y me he to_sql para "guiar" 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 puede ver, sigo usando SQL sin procesar, pero al menos solo está en la parte donde AR no brinda soporte (AFAIK ActiveRecord simplemente no puede administrar INNER JOIN ... ON ... ) y no en todo .

El uso de joins 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.