Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Penilaian persediaan saham berbasis FIFO di SQL Server

Anehnya sulit untuk mendapatkan yang benar. Saya menduga akan lebih mudah menggunakan SQL Server 2012 yang mendukung jumlah yang berjalan dalam fungsi windowing. Bagaimanapun:

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

Pengamatan pertama adalah kita tidak perlu melakukan sesuatu yang khusus untuk OUT transaksi - kita hanya perlu mengetahui jumlah totalnya. Itulah TotalOut CTE menghitung. Dua CTE pertama bekerja dengan IN transaksi, dan hitung "interval" stok yang diwakili masing-masing - ubah kueri akhir menjadi select * from RunningTotals untuk merasakannya.

SELECT terakhir pernyataan menemukan baris yang belum sepenuhnya habis oleh transaksi keluar, dan kemudian memutuskan apakah itu seluruh jumlah transaksi masuk itu, atau apakah itu transaksi yang melampaui total keluar.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Melewati output dari nilai yang identik di baris berikutnya

  2. Ubah float menjadi varchar di SQL Server tanpa notasi ilmiah

  3. Pertimbangan Keamanan SQL Server

  4. database terlampir hanya baca

  5. Bagaimana cara menghindari kesalahan pembagian dengan nol dalam SQL?