【问题标题】:Inventory recalculation given a final value给定最终值的库存重新计算
【发布时间】:2018-05-22 04:00:32
【问题描述】:

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

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

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

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

Inventory Recalculation on Excel

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

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

【问题讨论】:

  • 提示:查看 SUM() OVER ()

标签: sql sql-server tsql sql-server-2014


【解决方案1】:

您需要一个正在运行(或窗口化)的总和。

;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

【讨论】:

  • 嗨,我可以看到这条指令可以给我作为“RunningSum”的累积和。这还不是我要找的。我已经有最后一个库存水平。使用它,我的意图是计算前几天的水平(考虑(P.SUM_IN + P.SUM_OUT))。
  • @ArnoldSouza 然后使用 ORDER BY P.Date DESC 并将您的最终库存添加到 SUM(),例如 10 + SUM() OVER ()
【解决方案2】:

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

【讨论】:

  • 该指令导致从旧日期到最新日期的累积和。我已经有了最新的日期(即@last_stock int = 10),我想运行一个 SQL 来获取考虑 SUM_IN 和 SUM_OUT 的其他先前库存水平
【解决方案3】:

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

有没有更简单的方法来做到这一点?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 2021-03-30
    相关资源
    最近更新 更多