2013-11-14 3 views
3

У меня есть две таблицы. Один держит количество для определенной единицы. В других случаях количество, сроки и стоимость, когда эти единицы исторически прибыли.Расчет стоимости инвентаря в SQL

Таким образом, в моей первой таблице, я бы сказал БЛОКА «ABC» имеет величину 50

Во второй таблице, я бы данные, которые выглядят так:

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

Так что в этом Например, мне нужно будет вычислить значение 50 элементов на основе первой в первой системе. Математика будет выглядеть следующим образом для 50 пунктов:

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

Общее значение этого пункта будет $ 255,00

Так что мне нужно сделать, это около 300 000 пунктов, и я нужен «легкий кнопку». В настоящее время с использованием MS Access & SQL для моих данных. Поэтому любое решение, относящееся к любой из этих платформ, будет отличным.

+0

Если вы хотите ФИФО 50 пунктов «ABC», на основе данных во второй таблице, вы получите $ 3,00 с первого ряда. Если у вас было 110 предметов «ABC», стоимость единицы FIFO составляла бы $ 350/110. Это то, что тебе надо? Вы попросили «сначала сначала, но сначала», но у вас есть только «в». – WarrenT

+0

Я понял, что означает FIFO в этом контексте (я думаю). Фактически, запас загружается в порядке дат (FI), но предполагается, что все, что осталось на полке, только там, потому что любые предметы, вытащенные - были бы извлечены из самых ранних поставок (FO). Таким образом, стоимость любого имеющегося запаса будет рассчитана на основе последней цены последней поставки, а затем будет работать в обратном направлении до тех пор, пока стоимость акций не будет оценена. Очевидно, долгое время с тех пор, как я написал систему управления запасами ... – dav1dsm1th

+1

@ dav1dsm1th да, это имеет гораздо больше смысла и подходит к размещенным деталям. Я думаю, это показывает, что это было еще дольше, так как я работал над калькуляцией инвентаря, lol – 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

Ваш второй набор кода работал отлично (и быстро). Brilliant. – user2994049

Смежные вопросы