SQL SELECT 对选定行进行累积计算

SQL SELECT with cumulative calculation across selected rows

大家好,非常感谢您的帮助。

我卡在了查询的计算列上。我想计算每个订单所需单位的商品库存如何减少,因此我在 CALCULATEDSTOCK 列上有剩余库存信息。

对于每个 ARTICLE & COLOR & SIZE 的第一次出现,CALCULATEDSTOCK 是 "initial" 股票,对于 [=30= 的第二次和下一次出现]same ARTICLE & COLOR & SIZE CALCULATEDSTOCK 减少了之前需要的单位,所以我得到了该行的可用库存。

请注意,STOCK 始终与直接查询数据库相同。

这是我想要得到的结果:

ORDER   ARTICLE  COLOR    SIZE   STOCK   NEEDED   CALCULATEDSTOCK
-----------------------------------------------------------------
43002   1000     GREY     L      13      4        13
43002   1000     GREY     XL     20      5        20
43006   1000     GREY     XL     20      4        15 
43012   1000     GREY     XL     20      6        11
43021   1000     GREY     XL     20      2        5
43021   1000     PURPLE   M      7       2        7
43023   1000     PURPLE   L      6       3        6

在下面找到我尝试过的内容,但我无法将 LAG 命令应用于之前的 CALCULATEDSTOCK 列,因此我无法计算超过两行...

SELECT ORDER, ARTICLE, COLOR, SIZE, STOCK, NEEDED,
CAST( CASE WHEN ARTICLE = LAG(ARTICLE) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
   AND COLOR = LAG(COLOR) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
   AND SIZE = LAG(SIZE) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER)
THEN 
(lag(STOCK) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER))
-(lag(NEEDED) OVER (ORDER BY ARTICLE, COLOR, SIZE, ORDER))

ELSE STOCK
END
AS decimal(8, 2)) AS CALCULATEDSTOCK
.....

示例中有三行相同 ARTICLE&COLOR&SIZE 的 ORDERS,但还可以更多...

非常感谢您的耐心等待和甜蜜的问候!

我认为您缺少 PARTITION。另外,LAG 很棒,但是如果您只是做一种 运行 总计,那么 SUM 和一些计算就可以了。首先,您需要在源数据中有一个 ID;重复的列会搞砸。

with source (ORDER_id,   ARTICLE,  COLOR ,   SIZE,   STOCK,   NEEDED) as
(
select 43002,   1000   ,  'GREY  ',   'L '  ,   13   ,   4 union all 
select 43002,   1000   ,  'GREY  ',   'XL'  ,   20   ,   5 union all 
select 43006,   1000   ,  'GREY  ',   'XL'  ,   20   ,   4 union all 
select 43012,   1000   ,  'GREY  ',   'XL'  ,   20   ,   6 union all 
select 43021,   1000   ,  'GREY  ',   'XL'  ,   20   ,   2 union all 
select 43021,   1000   ,  'PURPLE',   'M '  ,   7    ,   2 union all 
select 43023,   1000   ,  'PURPLE',   'L '  ,   6    ,   3 
)
select id, order_id, article, color, size, stock, NEEDED, stock + needed - sum(needed) over (partition by ARTICLE, COLOR, SIZE order by id)
from (
    select row_number() over (order by order_id) id, ORDER_id, ARTICLE, COLOR, SIZE, STOCK, NEEDED
    from source
) source_with_id

可能有更优雅的方法来做到这一点,但这里有一个选择:

; with CTE as (select *
    , stock - sum(needed) over (partition by ARTICLE, color, size order by ORDER) as CalcNeeded
    , lead(ORDER) over (partition by ARTICLE, color, size order by ORDER) as PrevOrder
from MyTable)

select a.ORDER,
       a.ARTICLE,
       a.color,
       a.size,
       a.stock,
       a.needed,
       ISNULL(b.CalcNeeded, a.stock)
from cte a
left join cte b
on a.ARTICLE= b.ARTICLE and a.color = b.color and a.size = b.size
and a.ORDER = b.PrevOrder