| Module | ActiveRecord::Calculations::ClassMethods |
| In: |
vendor/rails/activerecord/lib/active_record/calculations.rb
|
Calculates the average value on a given column. The value is returned as a float, or nil if there‘s no row. See calculate for examples with options.
Person.average('age') # => 35.8
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 56
56: def average(column_name, options = {})
57: calculate(:avg, column_name, options)
58: end
This calculates aggregate values in the given column. Methods for count, sum, average, minimum, and maximum have been added as shortcuts. Options such as :conditions, :order, :group, :having, and :joins can be passed to customize the query.
There are two basic forms of output:
* Single aggregate value: The single value is type cast to Fixnum for COUNT, Float for AVG, and the given column's type for everything else.
* Grouped values: This returns an ordered hash of the values and groups them by the <tt>:group</tt> option. It takes either a column name, or the name
of a belongs_to association.
values = Person.maximum(:age, :group => 'last_name')
puts values["Drake"]
=> 43
drake = Family.find_by_last_name('Drake')
values = Person.maximum(:age, :group => :family) # Person belongs_to :family
puts values[drake]
=> 43
values.each do |family, max_age|
...
end
Options:
Examples:
Person.calculate(:count, :all) # The same as Person.count
Person.average(:age) # SELECT AVG(age) FROM people...
Person.minimum(:age, :conditions => ['last_name != ?', 'Drake']) # Selects the minimum age for everyone with a last name other than 'Drake'
Person.minimum(:age, :having => 'min(age) > 17', :group => :last_name) # Selects the minimum age for any family without any minors
Person.sum("2 * age")
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 125
125: def calculate(operation, column_name, options = {})
126: validate_calculation_options(operation, options)
127: column_name = options[:select] if options[:select]
128: column_name = '*' if column_name == :all
129: column = column_for column_name
130: catch :invalid_query do
131: if options[:group]
132: return execute_grouped_calculation(operation, column_name, column, options)
133: else
134: return execute_simple_calculation(operation, column_name, column, options)
135: end
136: end
137: 0
138: end
Count operates using three different approaches.
The third approach, count using options, accepts an option hash as the only parameter. The options are:
Examples for counting all:
Person.count # returns the total count of all people
Examples for counting by column:
Person.count(:age) # returns the total count of all people whose age is present in database
Examples for count with options:
Person.count(:conditions => "age > 26")
Person.count(:conditions => "age > 26 AND job.salary > 60000", :include => :job) # because of the named association, it finds the DISTINCT count using LEFT OUTER JOIN.
Person.count(:conditions => "age > 26 AND job.salary > 60000", :joins => "LEFT JOIN jobs on jobs.person_id = person.id") # finds the number of rows matching the conditions and joins.
Person.count('id', :conditions => "age > 26") # Performs a COUNT(id)
Person.count(:all, :conditions => "age > 26") # Performs a COUNT(*) (:all is an alias for '*')
Note: Person.count(:all) will not work because it will use :all as the condition. Use Person.count instead.
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 47
47: def count(*args)
48: calculate(:count, *construct_count_options_from_args(*args))
49: end
Calculates the maximum value on a given column. The value is returned with the same data type of the column, or nil if there‘s no row. See calculate for examples with options.
Person.maximum('age') # => 93
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 74
74: def maximum(column_name, options = {})
75: calculate(:max, column_name, options)
76: end
Calculates the minimum value on a given column. The value is returned with the same data type of the column, or nil if there‘s no row. See calculate for examples with options.
Person.minimum('age') # => 7
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 65
65: def minimum(column_name, options = {})
66: calculate(:min, column_name, options)
67: end
Calculates the sum of values on a given column. The value is returned with the same data type of the column, 0 if there‘s no row. See calculate for examples with options.
Person.sum('age') # => 4562
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 83
83: def sum(column_name, options = {})
84: calculate(:sum, column_name, options)
85: end
# File vendor/rails/activerecord/lib/active_record/calculations.rb, line 141
141: def construct_count_options_from_args(*args)
142: options = {}
143: column_name = :all
144:
145: # We need to handle
146: # count()
147: # count(:column_name=:all)
148: # count(options={})
149: # count(column_name=:all, options={})
150: case args.size
151: when 1
152: args[0].is_a?(Hash) ? options = args[0] : column_name = args[0]
153: when 2
154: column_name, options = args
155: else
156: raise ArgumentError, "Unexpected parameters passed to count(): #{args.inspect}"
157: end if args.size > 0
158:
159: [column_name, options]
160: end