2009-01-31 25 views
15

tengo un modelo Mail con el siguiente esquema:Contar y agrupar a la vez

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

Y quieren encontrar los 5 mejores países de la base de datos, por lo que seguir adelante y tipo

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

Esto me va a decir a los grupos (i necesita una orden de no sé cómo se escribe)

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

Esto me dirá cuántos mensajes hay en cada grupo

Im pregunto si puedo grupo y contar en tan sólo una sola vez

Respuesta

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

Esto debe darle registros que tienen un atributo de país y un atributo recuento.

+0

verdadera se debe utilizar en lugar de 't' – Swards

+1

@airportyh rieles API dice que ActiveRecord.find está en desuso (http://apidock.com/rails/ActiveRecord/Base/find/class). ¿Conoces la mejor manera de hacer esto en Rails 3? – dcarneiro

+1

@Daniel: Lo he pensado antes pero miro de cerca: dice "movido o en desuso" y en realidad se ha movido a ActiveRecord :: FinderMethods # find. (Creo que todavía se supone que debes llamar a Mail.find para acceder a este método en su nueva ubicación). – antinome

24

Probar:

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

no estoy seguro de recuento acepta :limit sin embargo.

EDIT:

creo que esto es más fácil de leer:

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

+0

Para usar la opción de límite, tienes que hacer lo siguiente: Mail.limit (10) .order ("count_all desc"). contar (grupo:: país). Similar a lo que sugiere tee. Para especificar condiciones, sugiero usar un alcance en el modelo o la opción where. – Hendrik

22

Con Rails 3 se puede simplificar aún más:

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

Usted puede ordenar por campos el grupo - en este caso solamente: el país sería válido:

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

También se puede pedir por el recuento, el uso de "count_all":

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

También puede limitar el número de grupos devuelto. Para ello hay que llamar límite antes de llamar recuento (porque #count vuelve ActiveSupport::OrderedHash):

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

sintaxis actualizada para Rieles 4:

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

yo también tenía a los datos del grupo con nombre de la ciudad y mostrando cuenta de cuántas filas hay para cada ciudad con condición específica. Así que esta es la forma en que lo hice:

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

salida de esta era:

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