2009-01-31 7 views
15

J'ai un modèle Mail avec le schéma suivant:comptage et le regroupement en même temps

t.string "mail" 
t.integer "country" 
t.boolean "validated" 
t.datetime "created_at" 
t.datetime "updated_at" 

Et je veux trouver les 5 premiers pays dans la base de données, donc j'aller de l'avant et de type

@top5 = Mail.find(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5) 

Cela me dire les groupes (i besoin d'un ordre par je ne sais pas comment écrire)

@top5 = Mail.count(:all,:group => 'country',:conditions => [ "validated = ?" , "t" ], :limit => 5) 

Cela me dire combien de mails sont dans chaque groupe

Im se demandant si je peux groupe et compter en un aller

Répondre

19
 
Mail.find(
    :all, 
    :select => 'count(*) count, country', 
    :group => 'country', 
    :conditions => ['validated = ?', 't' ], 
    :order => 'count DESC', 
    :limit => 5) 

Cela devrait vous donner des documents qui ont un attribut de pays et un attribut de comptage.

+0

vrai doit être utilisé au lieu de 't' – Swards

+1

@airportyh Rails API dit que ActiveRecord.find est obsolète (http://apidock.com/rails/ActiveRecord/Base/find/class). Connaissez-vous la meilleure façon de faire cela sur Rails 3? – dcarneiro

+1

@Daniel: J'y ai pensé avant mais j'y regarde de près: il est dit "déplacé ou déprécié" et en fait il a été déplacé vers ActiveRecord :: FinderMethods # find. (Je crois que vous êtes toujours supposé appeler Mail.find pour accéder à cette méthode dans son nouvel emplacement.) – antinome

24

Essayez:

Mail.count(:group => 'country', :conditions => ['validated = ?', 't'])

Je ne suis pas sûr comte accepte :limit bien.

EDIT:

Je pense que cela est plus facile à lire:

Mail.count(:group => :country, :conditions => {:validated => true})

+0

Pour utiliser l'option limite, vous devez faire: Mail.limit (10) .order ("count_all desc"). compter (groupe:: pays). Semblable à ce que le tee suggère. Pour spécifier les conditions, je suggère d'utiliser une portée sur le modèle ou l'option where. – Hendrik

22

Avec Rails 3, vous pouvez simplifier encore:

Mail.where(validated: true).count(group: :country) 

Vous pouvez commander par champs le groupe - dans ce cas seulement: le pays serait valide:

Mail.where(validated: true) 
    .order(:country) 
    .count(group: :country) 

Vous pouvez également commander par le comte, en utilisant « count_all »:

Mail.where(validated: true) 
    .order("count_all desc") 
    .count(group: :country) 

Vous pouvez également limiter le nombre de groupes retournés. Pour ce faire, vous devez appeler la limite avant d'appeler le nombre (car #count retours ActiveSupport::OrderedHash):

Mail.where(validated: true) 
    .order("count_all desc") 
    .limit(5) 
    .count(group: :country) 

syntaxe Mise à jour pour Rails 4:

Mail.where(validated: true) 
    .group(:country) 
    .count 
0

moi aussi eu des données de groupe avec nom de la ville et montrant compter de combien de lignes sont là pour chaque ville avec condition spécifique. Donc, voici comment je l'ai fait:

CityData.where(:status => 1).group(:city_name).count 

La sortie de c'était:

{:Mumbai => 10, :Dublin => 7, :SF => 9} 
Questions connexes