我有一个包含以下列的表
Period, WIP_Close, WIP_Open, WIP_Add, WIP_Minus.
我需要更新
然后
目前我使用光标如下:
declare y_curs cursor for select distinct period
from abc
order by period
declare @period as int
declare @old_period as int
set @old_period = 0
open y_curs
fetch y_curs into @period
while @@fetch_status = 0
begin
update f set f.wip_open = isnull(f1.wip_close,0)
from abc f join abc f1 on 1=1
where f.period = @period and f1.period=@old_period
update abc set wip_close = (isnull(wip_open,0) + wip_add - wip_minus) where period = @period
set @old_period = @period
fetch y_curs into @period
end
close y_curs
deallocate y_curs
这样可以正常工作并给出正确的结果,但是由于记录超过500万条,处理时间大约需要一个小时。
有没有更好的方法可以避免光标以获得更好的性能?
感谢您的任何建议。
此致
答案 0 :(得分:0)
抱歉,我没有数据来测试这个。设置一个样本表并试一试。
但也许是这样的:
WITH abc_Order (n,period,WIP_Close,WIP_Open,WIP_Add,WIP_Minus) AS (
select
ROW_NUMBER() OVER(
ORDER BY
period
) n,
n,period,WIP_Close,WIP_Open,WIP_Add,WIP_Minus
from abc
)
update curr
set
WIP_Open = prev.WIP_Close,
WIP_Close = prev.WIP_Close + curr.WIP_Add - curr.WIP_Minus
from abc_Order curr
inner join abc_Order prev on
curr.n = prev.n+1
答案 1 :(得分:0)
让我们制作一些测试数据
DECLARE @MyTable TABLE
(
Period int IDENTITY,
WIP_Open int,
WIP_Close int,
WIP_Add int,
WIP_Minus int
)
第一条记录具有默认的开放数据集。
INSERT INTO @MyTable
( WIP_Open, WIP_ADD, WIP_Minus )
VALUES
( 10, 1, 2 )
现在我们有一些加/卖库存的加/减
INSERT INTO @MyTable
( WIP_Add, WIP_Minus )
VALUES
( 2, 1 ),
( 5, 3 ),
( 6, 1 ),
( 1, 7 );
现在让我们总结所有的变化以及原始记录,以查看运行总计并获得每条记录的结束。
WITH T AS
(
SELECT
Period,
WIP_Open,
WIP_Add,
WIP_Minus,
SUM(ISNULL(WIP_Open, 0) + WIP_Add - WIP_Minus) OVER (ORDER BY Period) RunningWipClose
FROM @MyTable
)
SELECT * FROM T
这是输出:
Period WIP_Open WIP_Add WIP_Minus RunningWipClose
1 10 1 2 9
2 NULL 2 1 10
3 NULL 5 3 12
4 NULL 6 1 17
5 NULL 1 7 11
在此之后,使用滞后函数将空打开设置为prev close。
答案 2 :(得分:0)
Input -
period WIP_Close WIP_Open WIP_Add WIP_Minus
1 1 1 1 10
2 8 3 7 5
3 6 4 9 15
Output-
period WIP_Close WIP_Open WIP_Add WIP_Minus
1 1 1 1 10
2 3 1 7 5
3 -3 3 9 15
I guess you want to solve above problem.
Here is the solution.Let me know if you are not able to understand this.
SELECT * INTO #T
FROM
(
SELECT 1 period, 1 WIP_Close, 1 WIP_Open, 1 WIP_Add, 10 WIP_Minus UNION ALL
SELECT 2 period, 8 WIP_Close, 3 WIP_Open, 7 WIP_Add, 5 WIP_Minus UNION ALL
SELECT 3 period, 6 WIP_Close, 4 WIP_Open, 9 WIP_Add, 15 WIP_Minus ) TAB
SELECT * FROM #T
DECLARE @TopC INT = (SELECT TOP 1 WIP_Close FROM #T)
DECLARE @TopO INT = (SELECT TOP 1 WIP_Open FROM #T)
DECLARE @TopDIff INT = (SELECT TOP 1 WIP_Add - WIP_Minus FROM #T)
SELECT period,
@TopC + SUM(WIP_Add - WIP_Minus) OVER (ORDER BY period ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) - @TopDIff AS WIP_Close,
COALESCE(@TopC + SUM(WIP_Add - WIP_Minus) OVER (ORDER BY period ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) - @TopDIff,@TopO) AS WIP_Open,
WIP_Add,
WIP_Minus
FROM #T