sql查询fifo库存

时间:2019-08-06 05:15:46

标签: sql sql-server fifo

我遇到了一个关于fifo sql查询的简单问题(计算每个销售日的利润)。

有两个表“生产”和“发票”。对于每天的销售,我必须使用FIFO方法输出总销售利润。

例如,为了获得第二天的利润,我必须使用前一天的剩余项目及其价格。

这是表格和所需的输出结果

CREATE TABLE Production
(
    id int identity(1,1) primary key,
    Productid varchar(10),
    pdate date,
    Qty int,
    Price decimal(18, 2),
);

INSERT INTO Production (Productid,pDate, Qty ,Price) VALUES ('PD1', '01/01/2017', 8, 200);
INSERT INTO Production (Productid,pDate ,Qty ,Price) VALUES ('PD2', '02/01/2017', 14, 300);
INSERT INTO Production (Productid,pDate ,Qty ,Price) VALUES ('PD3', '03/01/2017', 15, 150);

CREATE TABLE Sales
(
    id int identity(1,1) primary key,
    Sid varchar(10),
    sDate date,
    Productid varchar(10),
    Qty int,
);

INSERT INTO Sales (Sid,sDate ,Productid ,Qty) VALUES ('S001', '04/01/2017', 'PD1', 5);
INSERT INTO Sales (Sid,sDate ,Productid ,Qty) VALUES ('S002', '05/01/2019', 'PD2', 4);
INSERT INTO Sales (Sid,sDate ,Productid ,Qty) VALUES ('S003', '06/01/2019', 'PD3', 6);

每天手动计算剩余的公式 (现有-销售数量)+购买数量=剩余

2 个答案:

答案 0 :(得分:1)

希望这会有所帮助。

SELECT 
     s.sid,
     s.sdate,
     p.productid,
     s.qty,
     CASE 
        WHEN s.qty <= p.qty 
            THEN s.qty*p.price 
        ELSE p.qty*p.price + (s.qty-p.qty) * (SELECT price FROM purchase WHERE pdate IN (SELECT MAX(pdate) FROM purchase WHERE pdate < s.sdate))
     END  AS PROFIT
 FROM purchase p
 JOIN sales s 
   ON p.productid = s.productid
      AND p.pdate = s.sdate

答案 1 :(得分:1)

我认为对sales.qty < purchase.qty进行简单的检查是行不通的。由于即使您有sales.qty < purchase.qty却有前一天的剩菜,那么您将首先使用那些剩菜。 您应该使用以下方法:

   with cte as(
select s.id,s.Sid,sDate,s.Productid,s.qty AS Qty,s.qty as saleqty,p.qty as productqty,p.price
  ,sum(p.qty-s.qty) over (order by sdate) as leftover
  from purchase P
inner join sales S
on p.productid=s.productid
and p.pdate=s.sdate
)
select id, Sid,sDate,Productid,Qty,
case when lag(leftover) over (order by sdate)>0 then lag(leftover *price) over( order by sdate)
+( saleqty-lag(leftover) over (order by sdate)) * price
else saleqty * price end as profit
from cte;