2014-12-13 79 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

相關問題