2013-11-14 3 views
3

두 테이블이 있습니다. 하나는 특정 단위에 대한 수량을 보유합니다. 다른 하나는이 단위가 역사적으로 도착했을 때 수량, 날짜 및 비용을 보유합니다. 그래서SQL의 재고 비용 계산

Unit Date arrived Quantity Cost 
---- ------------ -------- ----- 
ABC  11/1   100 $3.00 
ABC  11/4    15 $5.00 
ABC  11/5    25 $6.00 

을이에 :

그래서 내 첫 번째 테이블에, 나는 내가 다음과 같습니다 데이터를했을 두 번째 표에서 50

의 양을 가지고 UNIT "ABC"를 말할 것 예를 들어, 먼저 선입 선출 기준에 따라 50 개 항목의 가치를 파악해야합니다. 수학은 50 개 항목에 대해 다음과 같이 보일 것이다 :이 항목에 대한

25 x $6.00 
15 x $5.00 
10 x $3.00 

총 가치는 그래서 30 만 항목이 작업을 수행 할 필요가 $ 255.00

될 것이며, 나는 "쉬운 버튼을"이 필요합니다. 현재 내 데이터를 채굴하려면 & SQL을 사용하고 있습니다. 따라서 이러한 플랫폼 중 하나와 관련된 모든 솔루션은 훌륭합니다.

+0

두 번째 테이블의 데이터를 기준으로 FIFO 비용 50 "ABC"항목을 원하면 첫 번째 행에서 $ 3.00을 얻습니다. 110 개의 "ABC"항목이 있다면 FIFO 단위 비용은 $ 350/110이됩니다. 이게 니가 필요한거야? 당신은 "first in, first out"을 요구했지만 당신은 "in"만을 가지고 있습니다. – WarrenT

+0

나는이 문맥에서 FIFO가 무엇을 의미하는지 알아 냈다. 결과적으로, 주식은 날짜 순서 (FI)로 적재되지만, 선반에 남아있는 것은 선적 된 모든 품목이 초기 선적 (FO)에서 꺼내 졌을 것이기 때문에 선반에 남아있는 모든 것이 거기에 있다는 것입니다. 따라서 보유하고있는 주식의 가치는 최근 인도 시점의 최신 가격에서 산출되며, 주식의 가치가 평가 될 때까지 거꾸로 계산됩니다. 재고 관리 시스템을 작성한 이후로 오랜 시간이 걸렸습니다 ... – dav1dsm1th

+1

@ dav1dsm1th 네, 훨씬 더 의미가 있으며, 게시 된 세부 사항에 부합합니다. 나는 인벤토리 원가 계산에 대해 작업 한 이후로 더 오래되었음을 보여줍니다. – WarrenT

답변

2

이 : -

select s.unit, dv.cost_2d+((s.quantity-dv.quantity_2d)*dv.cost) as valuation 
from (
    select 
     d.*, 
     isnull((
      select sum(csq.quantity) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) as quantity_2d, 
     isnull((
      select sum(csq.quantity*csq.cost) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) as cost_2d 
    from #delivery d 

    -- possible optimization - reduces the number of rows 
    -- if we have enough to calculate value of stock held 

    --join #stock s on s.unit=d.unit 
    --and isnull((
    -- select sum(csq.quantity) 
    -- from #delivery csq 
    -- where csq.unit=d.unit 
    --  and csq.arrived>d.arrived 
    -- ),0)<=s.quantity 

    -- you'd need to test if it helps/hinders with your dataset/schema 

) as dv 
join #stock s on s.unit=dv.unit 
where dv.quantity+dv.quantity_2d>=s.quantity 
    and dv.quantity_2d<s.quantity 

는 생산 : -

unit valuation 
abc  255.00 

에서 공급하는 경우 : -

create table #stock (
    unit varchar(10), 
    quantity int 
) 

create table #delivery (
    unit varchar(10), 
    arrived date, 
    quantity int, 
    cost money 
) 

insert into #stock values ('abc',50) 
insert into #delivery values ('abc','2013-11-01',100,3) 
insert into #delivery values ('abc','2013-11-04',15,5) 
insert into #delivery values ('abc','2013-11-05',25,6) 

----------- UPDATE-- ---------------------------------

다른 버전이 있습니다. -

select dv.unit, dv.cost_2d+((dv.instock-dv.quantity_2d)*dv.cost) as valuation 
from (
    select 
     d.*, 
     isnull((
      select sum(csq.quantity) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) as quantity_2d, 
     isnull((
      select sum(csq.quantity*csq.cost) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) as cost_2d, 
     s.quantity as instock 
    from #delivery d 
    join #stock s on s.unit=d.unit 
    and s.quantity between isnull((
      select sum(csq.quantity) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) and isnull((
      select sum(csq.quantity) 
      from #delivery csq 
      where csq.unit=d.unit 
       and csq.arrived>d.arrived 
     ),0) + d.quantity 
) as dv 
+0

제 대답의 하단에 두 번째 최적화를 추가했습니다. 이것은 동일한 결과를 산출하며 OPs 환경에서 쿼리를보다 효율적으로 실행할 수 있습니다 (테스트 데이터가 너무 작아 코드의 장점/단점을 측정 할 수 없음). – dav1dsm1th

+0

이 점을 개선하고 파생 테이블 내에서 평가를 계산할 수 있어야합니다. 단순히 코드를 추가하면됩니다 (OP에 성능 문제가있는 경우 다시 돌아올 수 있습니다). – dav1dsm1th

+1

두 번째 코드 세트가 완벽하게 (그리고 빨리) 실행되었습니다. 훌륭한. – user2994049