2010-06-29 3 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 

입력 및 출력은 양의 값을 갖는다. 출력 수량 부정함으로써 제품 재고특정 제품 재고 나는,이 개 원시 SQL 쿼리에 UNION을 사용을 얻을, 다음 그룹을 함께 그들을 모두 정리해 :

그것은 작동
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 

,

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

모든 아이디어, 또는 I H를 수행하지만 액티브에 체인 쿼리에 named_scope의 기능을 사용하고 같은 일을 할 수 있도록하고 싶습니다 보다 편리한 스키마를 바꿀 수 있습니까? 감사!

답변

2

이 문제를 해결할 수있는 가능성이 너무 많습니다.이 보고서에서 정확히 무엇을 원하십니까?

구매 주문은 무엇입니까? 제품? 입력/출력?

UPDATE

을 시도

(당신이 가르치 려 제발 수 있다면 나는 당신의 질문에 대해 언급 할 수 없기 때문에 대답으로이 게시하도록하겠습니다, 나는 대답으로 업데이 트됩니다)

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

당신은

Input.by_product(25) 
,691를 호출하여 해당 제품 ID를 일치하는 입력을 얻을 수 있습니다

당신이 찾고있는 제품이라면 나는 제품별로 출력물을 너무 많이 만들 수 있다고 생각한다.]

+0

(입력 - 출력) –

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
빅터의 솔루션은 둘다 입력하여 제품을 복제합니다 가입하기 때문에 여러 "출력"기록이있을 때 실패

및 출력.

대신 실제 테이블 대신 파생 테이블을 사용하여 조인해야합니다. 이 어려운 데이터없이 테스트하고 보여하지만 당신은 이런 식으로 뭔가를 시도해야합니다 :

"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"절에 요소를 더 추가 할 수 있습니다. 이렇게하면 대부분의 방법을 얻을 수 있습니다. 또는 DB 다이어그램을 게시하여 테이블 관계를보다 잘 이해할 수 있도록하십시오.

+0

두 방법 모두 정확하지만 단순하지는 않지만 이름을 사용하고 싶다. 범위 –

+0

그래서 쿼리를 저장 프로 시저에 넣으시겠습니까? 내가 뭘 찾고 있는지 잘 모르겠다. 제품 별 – Matthew