使用Activerecord对多列进行求和

Joy*_*Joy 13 activerecord ruby-on-rails

我是Activerecord的新手.我想对模型学生的多个列进行求和.我的模范学生如下:

 class Student < ActiveRecord::Base
   attr_accessible :class, :roll_num, :total_mark, :marks_obtained, :section
 end
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西:

 total_marks, total_marks_obtained = Student.where(:id=>student_id).sum(:total_mark, :marks_obtained)
Run Code Online (Sandbox Code Playgroud)

但它给出了以下错误.

NoMethodError: undefined method `except' for :marks_obtained:Symbol
Run Code Online (Sandbox Code Playgroud)

所以我问我是否必须为上述模型查询两次,即一次查找总标记,另一次查找获得的标记.

pen*_*ner 16

如果需要,可以使用原始SQL.像这样返回一个你必须提取值的对象......我知道你指定了活动记录!

Student.select("SUM(students.total_mark) AS total_mark, SUM(students.marks_obtained) AS marks obtained").where(:id=>student_id)
Run Code Online (Sandbox Code Playgroud)

对于rails 4.2(之前未选中)

Student.select("SUM(students.total_mark) AS total_mark, SUM(students.marks_obtained) AS marks obtained").where(:id=>student_id)[0]
Run Code Online (Sandbox Code Playgroud)

注意声明后面的括号.没有它,语句将返回Class :: ActiveRecord_Relation,而不是AR实例.这有什么重要意义,你不能使用first这种关系.

....where(:id=>student_id).first #=> PG::GroupingError: ERROR:  column "students.id" must appear in the GROUP BY clause or be used in an aggregate function
Run Code Online (Sandbox Code Playgroud)

  • 这里应该注意,别名列名应该与表中的一个实际列名匹配 (4认同)
  • 不幸的是,这似乎并非在所有情况下都适用,例如尝试在关联表或带有 `includes()` 的连接表上进行选择。我发现你实际上可以在 `pluck()` 中提供聚合函数,例如 `Student.pluck("sum(total_mark)", "sum(marks_obtained)")` 作为回答:http://stackoverflow.com/a/ 41606066/2067695 (2认同)

Ale*_*uti 16

您可以使用pluck直接获得总和:

Student.where(id: student_id).pluck('SUM(total_mark)', 'SUM(marks_obtained)')
# SELECT SUM(total_mark), SUM(marks_obtained) FROM students WHERE id = ?
Run Code Online (Sandbox Code Playgroud)

您可以向pluck方法添加所需的列或计算字段,它将返回包含值的数组.

  • 只是想补充一点,这将返回嵌套在另一个数组中的数组(至少在 Rails 4.2 中),因此请记住对结果调用“flatten”。 (3认同)

Yas*_*gar 8

如果你只想要总和列total_marks和marks_obtained,试试这个

Student.where(:id=>student_id).sum('total_mark + marks_obtained')
Run Code Online (Sandbox Code Playgroud)