2014-12-13 88 views
1

如何使用Rails 3.2和MySql 5.5添加来自加入模型的字段的总和?如何在Rails中添加加入模型的字段总和?

比方说,我有模型是这样的:

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> 

我怎样才能做到这一点使用Rails(使用LEFT JOIN另一种方式来达到同样的效果。)?

我想是这样的:

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

尝试Operation.joins(:account).where(<mycondition>).sum(:amount)

领域正在总结amountoperations表;所以活动记录查询也将在Operation模型上。应该定义mycondition以包含属于特定帐户的操作。

+0

'Operation.joins(:帐户)'不工作,因为它没有返回有没有存款记录尚未账户。 我需要结果集中的这些帐户。 total_deposits应该为0。 – 2014-12-13 03:52:13

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 
+0

第一个解决方案生成我需要的SQL结果集,但其行在Ruby中作为数组返回。是否有可能获得Account实例? – 2014-12-13 04:04:02

+0

第二个解决方案不符合我的需求,因为我需要用'total_deposits desc'对结果集进行排序。 (为简单起见,我省略了原始问题中的排序。) – 2014-12-13 04:07:28

相关问题