3

次のような株式取引テーブルがあります。

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

FIFO (先入れ先出し) の各アイテムの在庫の値が必要です。つまり、最初に購入したアイテムを最初に消費する必要があります。上記のデータの出力在庫評価は次のとおりです。

Item  Qty      Value
ABC   50    40000.00
XYZ   110   37600.00

解決策を得るために私を助けてください。

4

2 に答える 2

5

正解するのは意外と難しい。ウィンドウ関数での合計の実行をサポートする 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- 総量を知る必要があるだけです。それがTotalOutCTEの計算です。最初の 2 つの CTE はINトランザクションを処理し、それぞれが表す在庫の「間隔」を計算します。最後のクエリを変更してselect * from RunningTotals、その感触をつかんでください。

最後のSELECTステートメントは、発信トランザクションによって完全に使い尽くされていない行を見つけ、それがその着信トランザクションの全量か、それとも発信合計にまたがるトランザクションかを判断します。

于 2012-04-26T07:02:33.543 に答える
0

これには詳細トランザクションテーブルを使用する必要があると思います。Stock、StockDetail、StockDetailTransactionのように。このStockDetailTransactionテーブルには、StockのFIFOエントリが含まれています。その時点でアイテムが出入りするときに、StockDetailTransactionにレコードを追加します。

于 2012-04-26T05:37:36.003 に答える