【问题标题】:T SQL Cumulative SubtractionT SQL 累加减法
【发布时间】:2019-10-19 19:35:48
【问题描述】:

我正在使用 MS SQL Server。

我有下表:

SKU     Shop    WeekNum    ShopPrioirty    Replen   OpeningStock
111     100         1            1           10          5000
111     200         1            2           10          NULL  
111     300         1            3           5           NULL
111     400         1            4           8           NULL

222     100         2            1           20          6000
222     200         2            2           15          NULL
222     300         2            3           12          NULL
222     400         2            4           10          NULL

这是想要的结果:

SKU     Shop    WeekNum    ShopPrioirty    Replen   OpeningStock
111     100         1            1           10          5000
111     200         1            2           10          4990  
111     300         1            3           5           4980
111     400         1            4           8           4975

222     100         2            1           20          6000
222     200         2            2           15          5980
222     300         2            3           12          5965
222     400         2            4           10          5953

对于给定的一周,一个 SKU 存在于多个商店中并被分配了一个优先级。在优先级 1 中分配期初库存。

但是,我需要更新期初库存(当前为 NULL)以等于之前的期初库存减去之前的补货。

在我尝试更新之前,我尝试只做一个 SELECT

SELECT SKU
      ,Shop
      ,WeekNum
      ,StorePriority
      ,Replen
      ,OpeningStock
      ,OpeningStock - Replen OVER (ORDER BY SKU,Shop,WeekNum ROWS UNBOUNDED PRECEDING) AS Opening
       FROM [table1] t

但我收到错误消息:Incorrect syntax near the keyword 'OVER'.

运行总和是正确的方法吗?

最好创建一个由 SKU\Shop\WeekNum\Priority 组成的密钥吗?

谢谢。

【问题讨论】:

  • 您缺少聚合函数。我假设你的意思是- SUM(Replen)而不是- Replen
  • 如果我将其更改为 SUM(Replen) 那么它只返回 1 个 OpeningStock 数字 - 我需要它运行
  • 鉴于每个SKU 严格来说有一个非空OpeningStock,一个选项是isnull(OpeningStock, sum(OpeningStock) over (partition by SKU) - sum(Replen) over (partition by SKU order by shop, weeknum, priority /* ?? */ rows between unbounded preceding and 1 preceding))
  • @GSerg 嗨 - 这不太正确。不过,我不想减去 Replen 的总和。它只需要是之前的 OpeningStock 减去之前的 Replen。
  • @Michael 数学上是一样的。

标签: sql sql-server tsql cumulative-sum


【解决方案1】:

我在这里对您的 PARTITION BYORDER BY 子句做了一些假设,但这会得到您想要的结果。由于您在第一行中只有OpeningStock 的值是SKU,所以我使用FIRST_VALUE 来获取第一个值,然后取走Replen 的所有 prior 值:

WITH VTE AS(
    SELECT *
    FROM (VALUES(111,100,1,1,10,5000),
                (111,200,1,2,10,NULL),  
                (111,300,1,3,5 ,NULL),
                (111,400,1,4,8 ,NULL),
                (222,100,2,1,20,6000),
                (222,200,2,2,15,NULL),
                (222,300,2,3,12,NULL),
                (222,400,2,4,10,NULL))V(SKU,Shop,WeekNum,ShopPrioirty,Replen,OpeningStock))
SELECT V.SKU,
       V.Shop,
       V.WeekNum,
       V.ShopPrioirty,
       V.Replen,
       V.OpeningStock,
       FIRST_VALUE(V.OpeningStock) OVER (PARTITION BY V.SKU ORDER BY V.ShopPrioirty,V.WeekNum ROWS UNBOUNDED PRECEDING) - 
       ISNULL(SUM(V.Replen) OVER (PARTITION BY V.SKU ORDER BY V.ShopPrioirty,V.WeekNum ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),0) AS CurrentStock
FROM VTE V;

【讨论】:

  • 这看起来就是我要找的 - 出于兴趣,“VTE”关键字是什么?
  • 这不是关键字,@Michael,这是我给 CTE(通用表表达式)起的名字。几年前,我在为 VALUES 子句编写 CTE 时犯了一个错字,这是一个很好的“快乐”巧合,从那时起我就一直在使用它。我称之为“值表表达式”
  • 解释一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 2015-06-04
  • 2017-10-27
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多