如何使用Rails 3.2和MySql 5.5添加联接模型中的字段总和?
我们说我有这样的模型:
class Account < ActiveRecord::Base
attr_accessible :number
has_many :operations
end
class Operation < ActiveRecord::Base
belongs_to :account
attr_accessible :op_type, # either 'deposit' or 'withdrawal'
:amount
end
我需要使用某些条件选择帐户,并为每个帐户添加所有存款的总和。
这可以通过SQL完成:
SELECT *,
IFNULL((
SELECT SUM(amount)
FROM operations
WHERE operations.account_id = accounts.id AND operations.op_type = 'deposit'
), 0) as total_deposits
FROM accounts
WHERE <condition for accounts>
(使用LEFT JOIN是获得相同结果的另一种方法。)
如何使用Rails做到这一点?
我想要这样的事情:
accounts = Account.where(<mycondition>). join(???). sum(???) # What should be here?
accounts.each do |a|
puts "Account #{a.number} has deposited #{a.total_deposits} total."
end
答案 0 :(得分:0)
尝试Operation.joins(:account).where(<mycondition>).sum(:amount)
求和的字段amount
位于operations
表中;所以活动记录查询也会在Operation
模型上。 mycondition
应定义为包含属于特定帐户的操作。
答案 1 :(得分:0)
如果您需要执行LEFT JOIN
来检索帐户,即使他们没有操作记录,您也需要输入该连接条件,例如:
totals = Account.where(<account conditions>).joins("LEFT JOIN operations ON operations.account_id = accounts.id AND operations.op_type = 'deposit'").group("accounts.number").sum(:amount)
totals.each do |a|
puts "Account #{a[0]} has deposited #{a[1]} total."
end
如果您愿意将其拆分为两个查询,这是一个选项:
accounts = Account.where(<account conditions>)
totals = Operation.where(op_type: "deposit", account_id: accounts.map(&:id)).group(:account_id).sum(:amount)
accounts.each do |a|
puts "Account #{a.number} has deposited #{totals[a.id] || 0} total."
end
编辑:如果你需要帐户实例并需要按总和排序,一些额外的SQL将开始蔓延。但这样的事情应该有效:
accounts = Account.where(<account conditions>).joins("LEFT JOIN operations ON operations.account_id = accounts.id AND operations.op_type = 'deposit'").group("accounts.number").select("accounts.*, COALESCE(SUM(amount), 0) AS acct_total").order("acct_total")
accounts.each do |a|
puts "Account #{a.number} has deposited #{a.acct_total} total."
end