具有 SQL 的先进先出库存

Fifo Inventory with SQL

第一次table我需要一个改编,因为有负面问题点,我需要净table考虑负面点作为第一次问题的借方。例如:

FechaEmi Cuenta PtosEmi PtosCan
30/06/2015  1   100     0
31/07/2015  1   120     0
31/08/2015  1   130     0
31/08/2015  1   0       55
30/09/2015  1   50      0
31/10/2015  1   30      0
30/11/2015  1   70      0
31/12/2015  1   95      0
31/01/2016  1   50      0
29/02/2016  1   0       74
31/03/2016  1   50      0
30/04/2016  1   15      0
30/06/2015  2   20      0
31/07/2015  2   30      0
31/08/2015  2   40      0
30/09/2015  2   350     0
30/06/2015  3   150     0
31/07/2015  3   120     0
31/08/2015  3   0       56
31/08/2015  3   220     0
30/06/2015  4   70      0
31/07/2015  4   134     0
31/08/2015  4   12      0
30/06/2015  5   97      0
31/07/2015  5   130     0
31/08/2015  5   15      0
30/09/2015  5   135     0
31/10/2015  5   20      0
30/11/2015  5   140     0
31/12/2015  5   25      0
31/01/2016  5   145     0
29/02/2016  5   0       25

其中:

FechaEmi= 日期;

昆塔=ID;

PtosEmi=问题点;

PtosCan=取消积分

我要这个table

FechaEmi    Cuenta  PtosEmi
30/06/2015  1   0
31/07/2015  1   91
31/08/2015  1   130
30/09/2015  1   50
31/10/2015  1   30
30/11/2015  1   70
31/12/2015  1   95
31/01/2016  1   50
31/03/2016  1   50
30/04/2016  1   15
30/06/2015  2   20
31/07/2015  2   30
31/08/2015  2   40
30/09/2015  2   350
30/06/2015  3   94
31/07/2015  3   120
31/08/2015  3   220
30/06/2015  4   70
31/07/2015  4   134
31/08/2015  4   12
30/06/2015  5   72
31/07/2015  5   130
31/08/2015  5   15
30/09/2015  5   135
31/10/2015  5   20
30/11/2015  5   140
31/12/2015  5   25
31/01/2016  5   145

我有这个代码。问题是对于在没有问题点的日期被记入借方的点数没有做任何事情。您如何建议我更改该查询?谢谢!

with cte as( 
select Fechaemi, Cuenta,PtosEmi,PtosCan
,row_number() over (partition by Fechaemi,Cuenta order by Fechaemi,Cuenta) as rank 
from emision) 
select a.Fechaemi, a.Cuenta,a.PtosEmi - coalesce(b.PtosCan, 0) stock 
from cte a 
left join cte b on 
a.FechaEmi= b.FechaEmi and a.Cuenta = b.Cuenta and a.rank = b.rank - 1 
where a.PtosEmi - coalesce(b.PtosCan, 0) > 0 order by a.cuenta asc, a.fechaemi asc

SQL FIDDLE DEMO

with totalPay as( 
    SELECT Cuenta, SUM(PtosCan) TotalPayment
    FROM emision
    GROUP BY Cuenta
),
totalDebt as (
    SELECT FechaEmi, Cuenta, (SELECT SUM(PtosEmi) 
                              FROM emision e2 
                              WHERE e2.FechaEmi <= e.FechaEmi
                              AND   e2.Cuenta = e.Cuenta                          
                             ) AS TotalDebt
    FROM emision e
    WHERE   e.PtosEmi <> 0
)
select  
    e.FechaEmi, 
    e.Cuenta, 
    e.PtosEmi, 
    td.TotalDebt, 
    tp.TotalPayment,
    CASE 
        WHEN td.TotalDebt < tp.TotalPayment THEN 0
        WHEN td.TotalDebt - tp.TotalPayment > PtosEmi THEN PtosEmi
        ELSE td.TotalDebt - tp.TotalPayment
    END Remaining
FROM 
    totalDebt  td inner join 
    totalPay tp on td.Cuenta = tp.Cuenta inner join
    emision e on td.FechaEmi = e.FechaEmi AND td.Cuenta = e.Cuenta
WHERE 
    e.PtosEmi <> 0

可能不是最优雅但明确的方式:

WITH 
PtosEmi AS(
  SELECT FechaEmi, cuenta, SUM(PtosEmi) as PtosEmi
  FROM table1
  GROUP BY FechaEmi, cuenta),
PtosCan AS (
  SELECT MIN(FechaEmi) as FechaEmi, cuenta, SUM(PtosCan) as PtosCan 
  FROM table1
  GROUP BY cuenta)
SELECT 
  e.FechaEmi, 
  e.cuenta, 
  e.ptosemi, 
  c.ptoscan,
  e.ptosemi - COALESCE(c.ptoscan, 0) total
FROM 
  PtosEmi e LEFT JOIN 
  PtosCan c ON e.FechaEmi = c.FechaEmi AND e.cuenta = c.cuenta
ORDER BY e.cuenta, e.FechaEmi

这是基于这样的假设,即在为 give cuenta 发布任何内容之前您不能取消。

此外,如果与最初发出的物品相比,您取消的物品总数更多,则总价值将为负数。

http://sqlfiddle.com/#!6/9ac40/11

更新

因为你想逐行减少取消,这里是更新的查询:

WITH 
ptosemi AS(
    SELECT FechaEmi, cuenta, 
           PtosEmi as PtosEmi,
           SUM(PtosEmi) OVER (PARTITION BY cuenta ORDER BY FechaEmi) runsum 
    FROM table1),
PtosCan AS (
    SELECT cuenta, SUM(PtosCan) as PtosCan 
    FROM table1
    GROUP BY cuenta)
SELECT 
  e.FechaEmi, 
  e.cuenta, 
  e.ptosemi, 
  e.runsum,
  c.ptoscan,
  CASE 
    WHEN e.runsum <= c.ptoscan
    THEN 0 
    WHEN c.ptoscan BETWEEN e.runsum - e.ptosemi AND e.runsum
    THEN e.runsum - COALESCE(c.ptoscan, 0)
    ELSE e.ptosemi END total
FROM 
 ptosemi e LEFT JOIN 
 PtosCan c ON e.cuenta = c.cuenta
ORDER BY e.cuenta, e.FechaEmi

http://sqlfiddle.com/#!6/8036c2/25