Вопрос по – Оценка запасов на основе FIFO в SQL Server [закрыто]

2

У меня есть таблица транзакций акций, как это:

<code>Item   Date         TxnType Qty  Price
ABC   01-April-2012   IN    200 750.00
ABC   05-April-2012   OUT   100     
ABC   10-April-2012   IN     50 700.00
ABC   16-April-2012   IN     75 800.00
ABC   25-April-2012   OUT   175     
XYZ   02-April-2012   IN    150 350.00
XYZ   08-April-2012   OUT   120     
XYZ   12-April-2012   OUT    10     
XYZ   24-April-2012   IN     90 340.00
</code>

Мне нужна стоимость инвентаря для каждого предмета в FIFO («первым пришел - первым обслужен»), то есть первый купленный предмет должен потребляться первым. Выходная оценка запасов вышеуказанных данных:

<code>Item  Qty      Value
ABC   50    40000.00
XYZ   110   37600.00
</code>

Пожалуйста, помогите мне получить решение.

Не могли бы вы объяснить, какие выходные данные вы должны суммировать? Arion

Ваш Ответ

2   ответа
0

Я думаю, что вы должны использовать подробную таблицу транзакций для этого. Как Stock, StockDetail, StockDetailTransaction. В этой таблице StockDetailTransaction содержится запись FIFO для акций. Когда Item In / Out в это время добавить запись в StockDetailTransaction.

4

Удивительно сложно получить права. Я подозреваю, что было бы проще использовать SQL Server 2012, который поддерживает запуск сумм в оконных функциях. Так или иначе:

declare @Stock table (Item char(3) not null,[Date] datetime not null,TxnType varchar(3) not null,Qty int not null,Price decimal(10,2) null)
insert into @Stock(Item ,  [Date] ,        TxnType, Qty,  Price) values
('ABC','20120401','IN',    200, 750.00),
('ABC','20120405','OUT',   100 ,null  ),
('ABC','20120410','IN',     50, 700.00),
('ABC','20120416','IN',     75, 800.00),
('ABC','20120425','OUT',   175, null  ),
('XYZ','20120402','IN',    150, 350.00),
('XYZ','20120408','OUT',   120 ,null  ),
('XYZ','20120412','OUT',    10 ,null  ),
('XYZ','20120424','IN',     90, 340.00);

;WITH OrderedIn as (
    select *,ROW_NUMBER() OVER (PARTITION BY Item ORDER BY [DATE]) as rn
    from @Stock
    where TxnType = 'IN'
), RunningTotals as (
    select Item,Qty,Price,Qty as Total,0 as PrevTotal,rn from OrderedIn where rn = 1
    union all
    select rt.Item,oi.Qty,oi.Price,rt.Total + oi.Qty,rt.Total,oi.rn
    from
        RunningTotals rt
            inner join
        OrderedIn oi
            on
                rt.Item = oi.Item and
                rt.rn = oi.rn - 1
), TotalOut as (
    select Item,SUM(Qty) as Qty from @Stock where TxnType='OUT' group by Item
)
select
    rt.Item,SUM(CASE WHEN PrevTotal > out.Qty THEN rt.Qty ELSE rt.Total - out.Qty END * Price)
from
    RunningTotals rt
        inner join
    TotalOut out
        on
            rt.Item = out.Item
where
    rt.Total > out.Qty
group by rt.Item

Первое наблюдение состоит в том, что нам не нужно делать ничего особенного дляOUT транзакции - нам просто нужно знать общее количество. Это то, чтоTotalOut CTE рассчитывает. Первые два CTE работают сIN транзакции и вычислить, какой «интервал» акций каждый представляет - измените окончательный запрос на простоselect * from RunningTotals чтобы почувствовать это.

ФиналSELECT Оператор находит строки, которые не были полностью исчерпаны исходящими транзакциями, и затем решает, является ли оно полным количеством этой входящей транзакции, или это транзакция, которая пересекает исходящую сумму.

Error: User Rate Limit Exceeded Nagesh
Error: User Rate Limit Exceeded Nagesh
Error: User Rate Limit ExceededinError: User Rate Limit Exceededout 10, inError: User Rate Limit ExceededoutError: User Rate Limit ExceededAError: User Rate Limit ExceededBError: User Rate Limit ExceededoutError: User Rate Limit Exceeded
Error: User Rate Limit Exceededinner joinError: User Rate Limit Exceededleft joinError: User Rate Limit Exceededout.QtyError: User Rate Limit ExceededCOALESCE(out.Qty,0)Error: User Rate Limit Exceeded

Похожие вопросы