Rob*_*ley 6 sql t-sql sql-server sql-server-2012
我正在使用SQL Server 2012来构建库存计划/重新排序引擎.
我有一堆过时的交易,称之为信用和借记.我想一次做两件事:
该表如下所示:
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);
Run Code Online (Sandbox Code Playgroud)
我正在使用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
Run Code Online (Sandbox Code Playgroud)
如果它低于零,我需要找到一种方法将运行总计(也就是RT)重置为零.
我的查询,其中数量和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
Run Code Online (Sandbox Code Playgroud)
Itzik Ben-Gan,Joe Celko或其他SQL英雄,你在外面吗?:)
提前致谢!
小智 12
这可以使用基于集合的解决方案来完成:
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);
干杯,Itzik
| 归档时间: |
|
| 查看次数: |
2244 次 |
| 最近记录: |