Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Funzioni finestra - Totale parziale con azzeramento

Questo può essere fatto utilizzando una soluzione basata su set:

1. Calcola il normale totale parziale (chiamalo RT)

2. Calcola il minimo corrente di RT (chiamalo MN)

Quando MN è negativo, -MN è la quantità totale che hai dovuto reintegrare finora. Sia replenish_rt -MN quando MN è negativo. Quindi, il nuovo totale parziale (chiamalo new_rt) è rt + replenish_rt. E se devi restituire la quantità di rifornimento corrente necessaria, sottrai il precedente replenish_rt (usando LAG) dalla corrente.

Ecco la domanda di soluzione completa:

with c1 as
(
  select *,
    sum(qty) over(order by tdate rows unbounded preceding) as rt
  from tx
),
c2 as
(
  select *,
    -- when negative, mn is the total qty that had to be
    -- replenished until now, inclusive
    min(rt) over(order by tdate rows unbounded preceding) as mn_cur
  from c1
)
select tdate, qty, rt,
  replenish_rt - lag(replenish_rt, 1, 0) over(order by tdate) as replenish,
  rt + replenish_rt as new_rt
from c2
  cross apply(values(case when mn_cur < 0 then -mn_cur else 0 end)) as a1(replenish_rt);
Saluti, Itzik