2010-06-29 68 views
6

我設計的庫存系統,它具有用戶產品buy_leads訂單(授權buy_leads),輸入輸出沒有UNION的庫存SQL查詢?

class Product < ActiveRecord::Base 
    has_many :buy_leads 
end 

class BuyLead < ActiveRecord::Base 
    belongs_to :product 
    has_one :order 
end 

class Order < ActiveRecord::Base 
    belongs_to :buy_lead 
    belongs_to :user, :foreign_key => :authorized_by 
    has_many :inputs 
end 

class Input < ActiveRecord::Base 
    belongs_to :order 
    has_many :outputs 
end 

class Output < ActiveRecord::Base 
    # Associations 
    belongs_to :input 
    belongs_to :user 
end 

輸入和輸出具有值。爲了得到產品庫存,並特定產品庫存我使用UNION兩個原始的SQL查詢,通過使輸出量負,然後組,總結他們一起:

class InventoryController < ApplicationController 

    def index 
    @inventory = Input.find_by_sql products_inventory_sql 
    end 

    def show 
    @inventory = Input.find_by_sql product_inventory_sql(params[:id]) 
    end 

private 

    def inputs_sql 
    "SELECT b.*, p.*, i.order_id, 
      i.id AS input_id, 
      i.quantity AS quantity  
    FROM inputs i 
      JOIN orders r ON r.id = i.order_id 
      JOIN buy_leads b ON b.id = r.buy_lead_id 
      JOIN products p ON p.id = b.product_id" 
    end 

    def outputs_sql 
    "SELECT b.*, p.*, i.order_id, 
      i.id AS input_id, 
      (o.quantity * -1) AS quantity 
    FROM outputs o 
      JOIN inputs i ON i.id = o.input_id 
      JOIN orders r ON r.id = i.order_id 
      JOIN buy_leads b ON b.id = r.buy_lead_id 
      JOIN products p ON p.id = b.product_id" 
    end 

    def products_inventory_sql 
    "SELECT *, SUM(quantity) AS remaining_qty 
    FROM (#{inputs_sql} UNION #{outputs_sql}) 
    GROUP BY product_id" 
    end 

    def product_inventory_sql(id) 
    "SELECT *, SUM(quantity) AS remaining_qty 
    FROM (#{inputs_sql} UNION #{outputs_sql}) 
    WHERE product_id = #{id} 
    GROUP BY order_id, input_id" 
    end 

end 

它的工作原理,但我想用named_scope的功能到鏈查詢在ActiveRecord的,並能夠做這樣的事情:

Product.inputs.by_product(id) 
Product.inventory.by_product(id) 
... 

任何想法,或者我^ h大大改變一個更方便的模式?謝謝!

回答

2

有太多的可能性來解決這個問題,你究竟想從這些報告中得到什麼?

買入訂單?產品?輸入/輸出?

(我張貼此作爲一個答案,因爲我不能對你的問題發表意見,我會回答更新,如果您能賜教)

UPDATE

試試這個

#on input 
named_scope :by_product, lambda {|id| {:joins => {:orders => {:buy_leads => :products}}, :conditions => ['products.id = ?', id]}} 

,並可以通過調用

Input.by_product(25) 
得到相匹配的產品ID的輸入

如果這就是你正在尋找我認爲你可以設法使輸出的產品也是如此:]

+0

(輸入 - 輸出),按產品 – 2010-07-24 06:10:43

0

我不能對此進行測試沒有數據,但我認爲它應該是這樣的:

SELECT 
     b.*, p.*, i.order_id, i.id AS input_id, i.quantity AS quantity, -o.quantity AS quantity, 
     (i.quantity - COALESCE(o.quantity,0)) AS remaining_qty 
FROM 
     products p 
     JOIN buy_leads b ON b.product_id = p.id 
     JOIN orders r ON r.buy_lead_id = b.id 
     JOIN inputs i ON i.order_id = r.id 
     LEFT JOIN outputs o ON o.input_id = i.id 
0

當有多個「輸出」的記載,因爲連接將通過兩個輸入複製產品維克多的解決方案失敗,輸出。

相反,您應該使用派生表而不是實際表來JOIN。 沒有數據,這是很難測試和演示,但你應該嘗試這樣的事:

"SELECT b.*, p.*, i.order_id, 
     i.id AS input_id, 
     i.quantity AS quantity, 
ISNULL(z.negquantities,0) negquantities, 
i.quantity + ISNULL(z.negquantities,0) sumquantities 

FROM inputs i 
     JOIN orders r ON r.id = i.order_id 
     JOIN buy_leads b ON b.id = r.buy_lead_id 
     JOIN products p ON p.id = b.product_id 
    JOIN 
    (SELECT SUM(-1 * o.quantity) NegQuantities, o.input_id FROM outputs o GROUP BY o.input_id) z 
    ON z.input_id = i.id 

你看要加入輸出表的總金額,由輸入ID分組,而不是輸出表本身。這可以消除連接中無意的行重複。 當然,您可以將更多元素添加到派生表(我稱之爲「z」)的「ON」列表或「Where」子句中。 這應該會讓您獲得大部分途徑。 或者,張貼一張數據庫圖表,以便我們更好地瞭解您的表格關係。

+0

這兩種方法似乎是正確的,但他們不使它更簡單,我想用Named範圍 – 2010-07-22 22:54:07

+0

因此將查詢放入存儲過程中? 我想我不確定你在找什麼? – Matthew 2010-07-22 23:03:09