Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Counting and grouping at the same time

I have a Mail model with the following schema:

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

And I want to find the top 5 countries in the database, so i go ahead and type

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

This will tell me the groups(i need an order by i dont know how to write)

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

This will tell me how many mails are in each group

Im wondering if i can group and count in just one go

like image 582
DFectuoso Avatar asked Jan 31 '09 23:01

DFectuoso


People also ask

Can we use count and group by together?

SQL – count() with Group By clause The count() function is an aggregate function use to find the count of the rows that satisfy the fixed conditions. The count() function with the GROUP BY clause is used to count the data which were grouped on a particular attribute of the table.

How do you play the game count to 20?

Sit or stand in a circle. The idea is for the group to count to twenty, one person saying one number at a time. Anybody can start the count. Then a different person says the next number – but if two or more people happen to speak at the same time, counting must start again from the beginning.

How do you play count off?

A group attempts to count from 1 to 20 in one shot, where people at random say one number at a time, without establishing a pattern or speaking over another person. A comfortable, open space. Minimum of 5 people.


2 Answers

Try:

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

I'm not sure count accepts :limit though.

EDIT:

I think this is more readable:

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

like image 132
Can Berk Güder Avatar answered Sep 22 '22 15:09

Can Berk Güder


With Rails 3 you can simplify it further:

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

You can order by fields in the group - in this case only :country would be valid:

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

You can also order by the count, using "count_all":

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

You can also limit the number of groups returned. To do this you must call limit before calling count (because #count returns ActiveSupport::OrderedHash):

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

Updated syntax for Rails 4:

Mail.where(validated: true)
    .group(:country)
    .count
like image 34
tee Avatar answered Sep 20 '22 15:09

tee