2008-10-09 7 views
9

Il s'agit d'une question ancienne où, avec une table avec les attributs 'type', 'variété' et 'price', vous récupérez l'enregistrement avec le prix minimum pour chaque type est.Récupérer le minimum/maximum pour chaque groupe dans ActiveRecord

Dans SQL, nous pouvons faire this par:

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

On pourrait peut-être imiter ce par:

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

Y at-il une meilleure mise en œuvre que cela?

+0

comment obtenir le prix maximum et minimum pour chaque type ?? – aashish

Répondre

0

Vous pouvez utiliser # find_by_sql, mais cela implique de renvoyer un objet de modèle, ce qui peut ne pas être ce que vous voulez.

Si vous voulez aller nu au métal, vous pouvez également utiliser # 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 est juste un outil. Vous l'utilisez quand c'est pratique. Quand SQL fait un meilleur travail, vous l'utilisez.

0

Je me bats avec cela depuis un moment et pour l'instant, il semble que vous soyez assez coincé avec la génération de SQL.

Cependant, j'ai quelques raffinements à offrir.

Au lieu de find_by_sql, comme @ François a suggéré, je l'ai utilisé ActiveRecord de to_sql et joins à "guide" mon SQL un peu:

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

Comme vous pouvez le voir, je suis toujours en utilisant SQL brut , mais au moins c'est seulement sur la partie où AR ne donne aucun support (AFAIK ActiveRecord ne peut tout simplement pas gérer INNER JOIN ... ON ...) et pas sur l'ensemble. L'utilisation de joins au lieu de find_by_sql rend la requête chainable - vous pouvez ajouter des conditions supplémentaires, ou trier la table, ou tout mettre dans une étendue.

Questions connexes