小编典典

窗口功能-重置运行总计

sql

我正在使用SQL Server 2012构建库存计划/重新排序引擎。

我有一堆过时的交易,称它们为贷方和借方。我想一次做两件事:

  1. 生成运行总计(每日净余额)
  2. 生成补充建议。补充将重置“总计”(在“#1”中)为零。

该表如下所示:

CREATE TABLE TX (TDate DATETIME, Qty   INT);

INSERT INTO TX VALUES ('2014-03-01', 20);  
INSERT INTO TX VALUES ('2014-03-02',-10); 
INSERT INTO TX VALUES ('2014-03-03',-20); 
INSERT INTO TX VALUES ('2014-03-04',-10); 
INSERT INTO TX VALUES ('2014-03-05', 30); 
INSERT INTO TX VALUES ('2014-03-06',-20);  
INSERT INTO TX VALUES ('2014-03-07', 10);  
INSERT INTO TX VALUES ('2014-03-08',-20); 
INSERT INTO TX VALUES ('2014-03-09', -5);

我正在使用SQL 2012 SUM OVER()窗口函数来显示这些的运行总数。

select TDate, Qty, RunningTotal, RecommendedReplenish from (
    select 
        TDate, 
        Qty, 
        SUM(Qty) OVER (ORDER BY TDate ROWS UNBOUNDED PRECEDING)  as RunningTotal,
        -1 * (CASE WHEN Qty < 0 AND SUM(Qty) OVER (ORDER BY TDate ROWS UNBOUNDED     PRECEDING) < 0 
                THEN 
            CASE WHEN Qty >  SUM(Qty) OVER (ORDER BY TDate ROWS UNBOUNDED PRECEDING)     THEN Qty ELSE SUM(Qty) OVER (ORDER                        BY TDate ROWS UNBOUNDED PRECEDING) END
        ELSE 0 END) as RecommendedReplenish
        /* Wrong, does not account for balance resetting to zero */
    from TX 
) T order by TDate

我需要找到一种方法将运行总计(又称RT)重置为零(如果下降到零以下)。

我的查询中Qty和RT均为负数,并将其中较大(较小的负数)作为第一个建议的补货。第一次可以正常运行。

我不确定如何从窗口运行总计中扣除这一点。如果可能的话,我想在一个语句中执行此操作。

以下是我要查找的输出的摘要:

TDate        Qty    R.Tot  Replenish     New RT
-----------  ----   -----  -----------  ---------
3/1/2014     20      20                    20
3/2/2014    -10      10                    10
3/3/2014    -20     -10       10            0
3/4/2014    -10     -20       10            0
3/5/2014     30      10                    30
3/6/2014    -20     -10                    10
3/7/2014     10       0                    20
3/8/2014    -20     -20                     0
3/9/2014    - 5     -25        5            0

Itzik Ben-Gan,Joe Celko或其他SQL英雄,您在那里吗?:)

提前致谢!


阅读 182

收藏
2021-05-05

共1个答案

小编典典

这可以使用基于集合的解决方案来完成:

1,计算出正常的跑步总数(称为RT)

2.计算RT的最小运行时间(称其为MN)

当MN为负时,-MN是您到目前为止必须补充的总量。当MN为负时,使replenish_rt为-MN。因此,新的运行总计(称为new_rt)为rt +
replenish_rt。并且,如果您需要返回当前所需的补货数量,请从当前值中减去以前的replenish_rt(使用LAG)。

这是完整的解决方案查询:

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);
2021-05-05