给定最终值的库存重新计算

Inventory recalculation given a final value

我正在编写一个 SQL 服务器脚本,以根据实际库存重新计算过去 365 天内从今天开始的特定 SKU 的库存。在脚本中,我做了很多数据清理操作。最后,输出是从临时 table 生成的,如下所示:

SELECT
    DATE,
    SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
    SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
    SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
    SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
FROM #MOVIMENTS
GROUP BY DT
ORDER BY DT

下面可以看到 SQL 的输出示例:

Table example

table 显示按日期分组的交易总和以及进出仓库的数量。我的目的是添加一个名为 "STOCK" 的列,该列显示代表日期的 SKU 的库存水平。为此,我拥有的是实际库存水平。所以我需要的是通过所有日期系列每天重新计算所有库存水平。

在 Excel 中很容易。我可以将实际级别放在最后一行(例如:10),然后扩展计算(图中显示的公式)直到到达顶部。如图所示(E 列是公式,G 列是输出):

Inventory Recalculation on Excel

有人可以帮我在 SQL 服务器中实现这个结果吗?

在 Python 中,我找到了一个 ,使用 Pandas,但我更愿意在 SQL 脚本中实现此计算。

SQL FIDDLE Example

SELECT
    DATE,
    SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
    SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
    SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
    SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
INTO #newtable
FROM #MOVIMENTS t1
GROUP BY DT
ORDER BY DT

select t1.DATE, t1.TRANSACTION_IN, t1.TRANSACTION_OUT, t1.SUM_IN, t1.SUM_OUT, SUM(t2.SUM_IN + t2.SUM_OUT) as STOCK
from #newtable t1
inner join #newtable t2 on t1.DATE >= t2.DATE
group by t1.DATE, t1.TRANSACTION_IN, t1.TRANSACTION_OUT, t1.SUM_IN, t1.SUM_OUT
order by t1.DATE

您需要 运行(或加窗)总和。

;WITH PartialResults AS
(
    SELECT
        DATE,
        SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
        SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
        SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
        SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
    FROM #MOVIMENTS
    GROUP BY DT
)
SELECT
    P.*,
    RunningSum = SUM(P.SUM_IN + P.SUM_OUT) OVER (ORDER BY P.Date ASC)
FROM
    PartialResults AS P

SQL Fiddle Example

根据@EzLo 的想法,我找到了解决这个问题的方法。

DECLARE @cum_sum float -- scalar cumulated sum
DECLARE @last_stock float = 10 -- current stock level

-- get the last value of the cumulated sum 
SELECT TOP 1 @cum_sum = SUM(SUM_IN + SUM_OUT) OVER (ORDER BY Date ASC) FROM t ORDER BY DATE DESC

-- final select
SELECT 
  *,
  RunningSum = SUM(SUM_IN + SUM_OUT) OVER (ORDER BY Date ASC) - (@cum_sum - @last_stock)
FROM t

有更简单的方法吗?