【问题标题】:CTE approach to avoid cursor update of each rows of table on result of previous row setsCTE 方法避免在先前行集的结果上对表的每一行进行游标更新
【发布时间】:2023-03-28 03:55:02
【问题描述】:

我想迭代地更新每一行,当行更新时它应该使用以前最新的更新值,但是通过使用 CTE 方法来避免游标

光标伪代码:

Cursor{

--when cursor on row 1
update @table
set Balance=dbo.somefunction(sum of balance before row<1 i.e 0)

--when cursor on row 2
update @table
set Balance=dbo.somefunction(sum of balance before row<2 i.e 950)
.
.
.

};

Declare @table table(id int,col int,col2 int,balance int);

INSERT INTO @table
values(1,200,50,0),(2,60,150,0),(3,250,3,0),(4,65,2,0);

最终结果如下所示:

1   200 50  950
2   60  150 1
3   250 3   3
4   65  2   50

【问题讨论】:

  • 您是否意识到您想要的结果与样本数据不一致?那 950 是从哪里来的?。
  • 您为什么使用 SQL Server 2008?它不再受支持。

标签: sql sql-server-2008 common-table-expression


【解决方案1】:

row_number() 函数通常用于识别前面的行。

with cte as (
  select *, row_number() over (order by id) as row
  from table
)
select *, 
       (select sum(cte2.balance)
        from cte as cte2
        where cte2.row < cte1.row) as SumBalance
from cte as cte1
order by id

虽然您的 id 列已经可以完成识别先前行的相同任务,但您并不真的需要 CTE。

select *, 
       (select sum(cte2.balance)
        from cte as cte2
        where cte2.id < cte1.id) as SumBalance
from cte as cte1
order by id

最后,您可以使用变量来存储和增加余额总和,因此您甚至不需要子查询。

declare @SumBalance int = 0

select *, @SumBalance = @SumBalance + Balance as SumBalance
from table
order by id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    相关资源
    最近更新 更多