Chr*_*ton 8 ruby activerecord ruby-on-rails
我想一次做几个聚合函数,例如获取按状态分组的最大和最小ID:
Model.maximum(:id).minimum(:id).group(:status)
Run Code Online (Sandbox Code Playgroud)
这不起作用(至少使用Rails 3.1.1) - 你在最小调用上得到一个错误,说它没有在Fixnum上定义.
NoMethodError: undefined method `minimum' for 22377:Fixnum
Run Code Online (Sandbox Code Playgroud)
我可以为它做原始的SQL - 但只是想知道是否有更高级别/ Rails选项...
谢谢,克里斯
And*_*sch 15
我有一个类似的问题,我用Rails 4中的组来解决.例如
Model.group(:status).pluck('min(id)','max(id)')
Run Code Online (Sandbox Code Playgroud)
也适用于拥有,订购等和计算列.
Model.group('CAST(created_at AS Date), EXTRACT(HOUR FROM created_at), floor(EXTRACT(MINUTE FROM created_at)/15) * 15')
.having('count(id) > 10')
.order('min(created_at)')
.pluck('count(id)')
Run Code Online (Sandbox Code Playgroud)
干杯
Jor*_*ing 14
我相信@topek是对的,你不能像这样链接计算功能.我认为你必须在select谓词中使用SQL ,例如:
Model.select('MAX(id) AS `maximum`, MIN(id) AS `minimum`').group(:status)
Run Code Online (Sandbox Code Playgroud)
我刚刚在我自己的项目中对此进行了测试,它似乎按预期工作.
我认为这些聚合函数不可能做到这一点,因为它们返回一个值而不是范围,请参阅文档。它们都使用计算方法,如您所见,该方法返回一个数字:
# File lib/active_record/calculations.rb, line 117
117: def calculate(operation, column_name, options = {})
118: validate_calculation_options(operation, options)
119: column_name = options[:select] if options[:select]
120: column_name = '*' if column_name == :all
121: column = column_for column_name
122: catch :invalid_query do
123: if options[:group]
124: return execute_grouped_calculation(operation, column_name, column, options)
125: else
126: return execute_simple_calculation(operation, column_name, column, options)
127: end
128: end
129: 0
130: end
Run Code Online (Sandbox Code Playgroud)
如果你想这样做,你必须手工制作查询。
下面是一个例子:
sql = "SELECT max(id) as max_id,
min(id) as min_id
FROM model
GROUP
BY status
"
Model.find_by_sql(sql).each do |row|
puts "min. id: #{row.min_id}, " <<
"max. id: #{row.max_id}, "
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11385 次 |
| 最近记录: |