根据不同的列计算 运行 总摘要

Calculate Running Total Summary based on Different column

我需要如下输出

StockQty = 10
Balance Qty [Allocate Stock Qty] Shortage [Stock] Running Stock
5.000 5.000 0.000 5.000
10.000 5.000 5.000 0.000
5.000 0.000 5.000 0.000
10.000 0.000 10.000 0.000
15.000 0.000 15.000 0.000

到目前为止我已经尝试过了,但还是做不到

declare @tbl as table
(
 ItemId int,
 BalanceQty int,
 CreateDate datetime,
 StockQty int
)


insert into @tbl values 
(1,5,'2021-12-16 19:28:32.200',10), 
(1,10,'2021-12-18 19:28:34.200',30),
(1,5,'2021-12-19 19:28:35.200',30),
(1,10,'2021-12-21 19:28:35.200',30),
(1,15,'2021-12-22 19:28:35.200',30)
 


 
update x 
set    x.StockQty = tx.StockQty  
from   @tbl x
join 
(
       select * 
       from 
       (
              select *,
                     ROW_NUMBER()over(partition by itemid order by CreateDate) as RowNo 
              from   @tbl  
       ) as t 
       where t.RowNo = 1
 ) as tx on tx.CreateDate = x.CreateDate
 

 update x 
 set    x.StockQty = 0 
 from   @tbl x
 join 
 (
        select * 
        from 
        (
              select *,
                     ROW_NUMBER()over(partition by itemid order by CreateDate) as RowNo 
              from @tbl  
        ) as t 
        where  t.RowNo != 1
  ) as tx on tx.CreateDate = x.CreateDate
 

select *, 
       case when SUM(StockQty - BalanceQty)
                 over(partition by ItemId 
                 order by CreateDate   Rows BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) < 0 
            then 0
            else SUM(StockQty - BalanceQty)
                 over(partition by ItemId order by CreateDate   Rows BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
            end      as [Running Stock] 
 from  @tbl 
--ORDER BY CreateDate

我想根据给定数据计算 运行 库存摘要 对于第一行 StockQty = 10,[Allocate Stock Qty] = StockQty - Balance Qty [会给你5个] [运行 Stock] = left stock Qty [5 utilize and 5 left] 短缺 [库存] 将为零,因为还没有短缺

对于第二行 StockQty = 5 因为我们在第一行使用了 [分配库存数量] = 运行 库存剩余的数量,即 5 [运行 Stock] = nothing left 所以 0 Shortage [Stock] 将是 5 因为我们 分配 5 我们没有库存等等

你可以使用递归 cte

with 
cte as
(
    select  *, rn = row_number() over (partition by ItemId order by CreateDate)
    from    @tbl 
),
rcte as
(
    -- anchor member
    select  rn, ItemId, StockQty, BalanceQty, 
            [Allocated Stock Qty]   = case when StockQty > BalanceQty
                                           then BalanceQty
                                           else StockQty
                                           end,
            [Shortage Stock]        = case when StockQty > BalanceQty
                                           then 0
                                           else BalanceQty - StockQty
                                           end,
            [Running Stock]         = StockQty - BalanceQty
    from    cte
    where   rn  = 1

    union all

    -- recursive member
    select  c.rn, c.ItemId, r.StockQty, c.BalanceQty,
           [Allocated Stock Qty]    = case when r.[Running Stock] > c.BalanceQty
                                           then c.BalanceQty
                                           else r.[Running Stock]
                                           end,
           [Shortage Stock]         = case when r.[Running Stock] > c.BalanceQty
                                           then 0
                                           else c.BalanceQty - r.[Running Stock]
                                           end,
           [Running Stock]          = case when r.[Running Stock] - c.BalanceQty > 0
                                           then r.[Running Stock] - c.BalanceQty
                                           else 0
                                           end
    from    cte c
            inner join rcte r   on  c.ItemId    = r.ItemId
                                and c.rn        = r.rn + 1
 )
 select *
 from   rcte
 order by rn
declare @tbl as table
(
 ItemId int,
 BalanceQty int,
 CreateDate datetime,
 StockQty int
)


insert into @tbl values 
(1,3,'2021-12-16 19:28:32.200',10), 
(1,10,'2021-12-18 19:28:34.200',30),
(1,5,'2021-12-19 19:28:35.200',30),
(1,10,'2021-12-21 19:28:35.200',30),
(1,15,'2021-12-22 19:28:35.200',30)
 


 
update x set x.StockQty = tx.StockQty  from @tbl x
join 
(select * from 
(
select *,ROW_NUMBER()over(partition by itemid order by CreateDate) as RowNo from @tbl  
)as t where t.RowNo = 1) as tx on tx.CreateDate = x.CreateDate
 

 update x set x.StockQty = 0 from @tbl x
join 
(select * from 
(
select *,ROW_NUMBER()over(partition by itemid order by CreateDate) as RowNo from @tbl  
)as t where t.RowNo != 1) as tx on tx.CreateDate = x.CreateDate
 

;with 
cte as
(
    select  *, rn = row_number() over (partition by ItemId order by CreateDate)
    from    @tbl 
),
rcte as
(
    -- anchor member
    select  rn, ItemId, StockQty, BalanceQty, 
            [Allocated Stock Qty]   =  BalanceQty,
            [Shortage Stock]        = case when StockQty > BalanceQty
                                           then 0
                                           else abs(BalanceQty - StockQty)
                                           end,
            [Running Stock]         =   case when StockQty - BalanceQty < 0
                                           then 0
                                           else abs(BalanceQty - StockQty)
                                           end 
    from    cte
    where   rn  = 1

    union all

    -- recursive member
    select  c.rn, c.ItemId, r.StockQty, c.BalanceQty,
           [Allocated Stock Qty]    =   r.[Running Stock],
           [Shortage Stock]         = case when r.[Running Stock] > c.BalanceQty
                                           then 0
                                           else c.BalanceQty - r.[Running Stock]
                                           end,
           [Running Stock]          = case when r.[Running Stock] - c.BalanceQty > 0
                                           then r.[Running Stock] - c.BalanceQty
                                           else 0
                                           end
    from    cte c
            inner join rcte r   on  c.ItemId    = r.ItemId
                                and c.rn        = r.rn + 1
 )
 select *
 from   rcte
 order by rn